@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.
- package/README.md +160 -0
- package/assets/preview-html.xsl +230 -0
- package/assets/upstream.json +7 -0
- package/assets/xsl/README.md +31 -0
- package/assets/xsl/entities.ent +154 -0
- package/assets/xsl/extract-asymptote.xsl +68 -0
- package/assets/xsl/extract-biblio-csl.xsl +327 -0
- package/assets/xsl/extract-datafile.xsl +71 -0
- package/assets/xsl/extract-dynamic.xsl +139 -0
- package/assets/xsl/extract-identity.xsl +136 -0
- package/assets/xsl/extract-interactive.xsl +81 -0
- package/assets/xsl/extract-latex-image.xsl +118 -0
- package/assets/xsl/extract-mermaid.xsl +58 -0
- package/assets/xsl/extract-mom.xsl +63 -0
- package/assets/xsl/extract-pg.xsl +2897 -0
- package/assets/xsl/extract-prefigure.xsl +157 -0
- package/assets/xsl/extract-qrcode.xsl +100 -0
- package/assets/xsl/extract-runestone-page-template.xsl +139 -0
- package/assets/xsl/extract-sageplot.xsl +166 -0
- package/assets/xsl/extract-stack.xsl +56 -0
- package/assets/xsl/extract-trace.xsl +134 -0
- package/assets/xsl/extract-youtube.xsl +63 -0
- package/assets/xsl/html-symbols.xsl +3344 -0
- package/assets/xsl/latex/pretext-latex-AIM.xsl +56 -0
- package/assets/xsl/latex/pretext-latex-CLP.xsl +148 -0
- package/assets/xsl/latex/pretext-latex-chaos.xsl +317 -0
- package/assets/xsl/latex/pretext-latex-dyslexic-font.xsl +76 -0
- package/assets/xsl/latex/pretext-latex-guide.xsl +104 -0
- package/assets/xsl/latex/pretext-latex-texstyle.xsl +862 -0
- package/assets/xsl/localizations/README.md +56 -0
- package/assets/xsl/localizations/af-ZA.xml +276 -0
- package/assets/xsl/localizations/bg-BG.xml +276 -0
- package/assets/xsl/localizations/ca-ES.xml +285 -0
- package/assets/xsl/localizations/cs-CZ.xml +280 -0
- package/assets/xsl/localizations/de-DE.xml +281 -0
- package/assets/xsl/localizations/en-US.xml +427 -0
- package/assets/xsl/localizations/es-ES.xml +287 -0
- package/assets/xsl/localizations/fi-FI.xml +275 -0
- package/assets/xsl/localizations/fr-CA.xml +276 -0
- package/assets/xsl/localizations/fr-FR.xml +280 -0
- package/assets/xsl/localizations/hu-HU.xml +280 -0
- package/assets/xsl/localizations/it-IT.xml +276 -0
- package/assets/xsl/localizations/ku-CKB.xml +275 -0
- package/assets/xsl/localizations/localizations.xml +48 -0
- package/assets/xsl/localizations/nl-NL.xml +275 -0
- package/assets/xsl/localizations/pt-BR.xml +288 -0
- package/assets/xsl/localizations/pt-PT.xml +292 -0
- package/assets/xsl/localizations/zh-HANS.xml +269 -0
- package/assets/xsl/pretext-assembly.xsl +4795 -0
- package/assets/xsl/pretext-basic-html.xsl +86 -0
- package/assets/xsl/pretext-beamer.xsl +662 -0
- package/assets/xsl/pretext-braille-preprint.xsl +2249 -0
- package/assets/xsl/pretext-common.xsl +12018 -0
- package/assets/xsl/pretext-dynamic.xsl +65 -0
- package/assets/xsl/pretext-epub.xsl +1483 -0
- package/assets/xsl/pretext-fo.xsl +4593 -0
- package/assets/xsl/pretext-html.xsl +14791 -0
- package/assets/xsl/pretext-json-manifest.xsl +150 -0
- package/assets/xsl/pretext-jupyter.xsl +868 -0
- package/assets/xsl/pretext-latex-classic.xsl +952 -0
- package/assets/xsl/pretext-latex-common.xsl +11563 -0
- package/assets/xsl/pretext-latex.xsl +47 -0
- package/assets/xsl/pretext-litprog.xsl +105 -0
- package/assets/xsl/pretext-merge.xsl +41 -0
- package/assets/xsl/pretext-numbers.xsl +875 -0
- package/assets/xsl/pretext-revealjs.xsl +522 -0
- package/assets/xsl/pretext-runestone-fitb.xsl +1233 -0
- package/assets/xsl/pretext-runestone-static.xsl +1438 -0
- package/assets/xsl/pretext-runestone.xsl +3083 -0
- package/assets/xsl/pretext-sage-doctest.xsl +289 -0
- package/assets/xsl/pretext-smc.xsl +492 -0
- package/assets/xsl/pretext-solution-manual-latex.xsl +323 -0
- package/assets/xsl/pretext-text-utilities.xsl +1217 -0
- package/assets/xsl/pretext-text.xsl +392 -0
- package/assets/xsl/pretext-units.xsl +195 -0
- package/assets/xsl/pretext-view-source.xsl +157 -0
- package/assets/xsl/pretext-ww-problem-sets.xsl +391 -0
- package/assets/xsl/publisher-variables.xsl +4756 -0
- package/assets/xsl/support/README.md +22 -0
- package/assets/xsl/support/extract-math.xsl +256 -0
- package/assets/xsl/support/package-math.xsl +141 -0
- package/assets/xsl/support/play-button/README.md +46 -0
- package/assets/xsl/support/play-button/play-button.png +0 -0
- package/assets/xsl/support/play-button/play-button.svg +3 -0
- package/assets/xsl/support/pretext-pg-macros.xsl +110 -0
- package/assets/xsl/support/webpack_static_imports.xml +14 -0
- package/assets/xsl/tests/README.md +24 -0
- package/assets/xsl/tests/null.xml +4 -0
- package/assets/xsl/tests/pretext-text-utilities-test.xsl +334 -0
- package/assets/xsl/utilities/README.md +31 -0
- package/assets/xsl/utilities/author-report.xsl +107 -0
- package/assets/xsl/utilities/deprecate-autoname.sed +18 -0
- package/assets/xsl/utilities/deprecate-index.sed +33 -0
- package/assets/xsl/utilities/fix-deprecations.xsl +663 -0
- package/assets/xsl/utilities/pretext-enhanced-source.xsl +112 -0
- package/assets/xsl/utilities/report-publisher-variables.xsl +162 -0
- package/assets/xsl/xml-to-json.xsl +326 -0
- package/assets/xsl/xml-to-string.xsl +328 -0
- package/cli.mjs +29 -0
- package/dist/cli-C6tfAVvi.js +553 -0
- package/dist/cli.d.ts +10 -0
- package/dist/cli.js +7 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +10 -0
- package/dist/mounts.d.ts +23 -0
- package/dist/publication.d.ts +16 -0
- package/dist/renderer.d.ts +84 -0
- package/dist/sourcemap.d.ts +41 -0
- package/dist/xinclude.d.ts +45 -0
- package/package.json +52 -0
|
@@ -0,0 +1,4593 @@
|
|
|
1
|
+
<?xml version='1.0'?>
|
|
2
|
+
|
|
3
|
+
<!--********************************************************************
|
|
4
|
+
Copyright 2026 Robert A. Beezer
|
|
5
|
+
|
|
6
|
+
This file is part of PreTeXt.
|
|
7
|
+
|
|
8
|
+
PreTeXt is free software: you can redistribute it and/or modify
|
|
9
|
+
it under the terms of the GNU General Public License as published by
|
|
10
|
+
the Free Software Foundation, either version 2 or version 3 of the
|
|
11
|
+
License (at your option).
|
|
12
|
+
|
|
13
|
+
PreTeXt is distributed in the hope that it will be useful,
|
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
GNU General Public License for more details.
|
|
17
|
+
|
|
18
|
+
You should have received a copy of the GNU General Public License
|
|
19
|
+
along with PreTeXt. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
*********************************************************************-->
|
|
21
|
+
|
|
22
|
+
<!-- http://pimpmyxslt.com/articles/entity-tricks-part2/ -->
|
|
23
|
+
<!DOCTYPE xsl:stylesheet [
|
|
24
|
+
<!ENTITY % entities SYSTEM "entities.ent">
|
|
25
|
+
%entities;
|
|
26
|
+
]>
|
|
27
|
+
|
|
28
|
+
<!-- Conversion of PreTeXt source to XSL Formatting Objects (XSL-FO), -->
|
|
29
|
+
<!-- a LaTeX-free route to a PDF. A formatter, such as Apache FOP, -->
|
|
30
|
+
<!-- renders the resulting *.fo file as a PDF. This conversion is -->
|
|
31
|
+
<!-- experimental and very incomplete; see doc/pretext-fo-roadmap.md -->
|
|
32
|
+
<!-- for the development plan, and see the coverage harness at the end -->
|
|
33
|
+
<!-- of this stylesheet for the development workflow. -->
|
|
34
|
+
<xsl:stylesheet
|
|
35
|
+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
|
|
36
|
+
xmlns:xml="http://www.w3.org/XML/1998/namespace"
|
|
37
|
+
xmlns:pi="http://pretextbook.org/2020/pretext/internal"
|
|
38
|
+
xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
|
39
|
+
xmlns:svg="http://www.w3.org/2000/svg"
|
|
40
|
+
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"
|
|
41
|
+
xmlns:exsl="http://exslt.org/common"
|
|
42
|
+
xmlns:str="http://exslt.org/strings"
|
|
43
|
+
xmlns:pf="https://prefigure.org"
|
|
44
|
+
extension-element-prefixes="exsl str"
|
|
45
|
+
exclude-result-prefixes="pi svg pf str"
|
|
46
|
+
>
|
|
47
|
+
|
|
48
|
+
<!-- Standard conversion groundwork -->
|
|
49
|
+
<xsl:import href="./publisher-variables.xsl"/>
|
|
50
|
+
<xsl:import href="./pretext-assembly.xsl"/>
|
|
51
|
+
<xsl:import href="./pretext-common.xsl"/>
|
|
52
|
+
|
|
53
|
+
<!-- The "indent" attribute is deliberately absent. Indentation makes -->
|
|
54
|
+
<!-- the *.fo file much easier to study, but introduces whitespace -->
|
|
55
|
+
<!-- into mixed content that we cannot control for: an isolated, -->
|
|
56
|
+
<!-- entirely inline, "segment" of a paragraph would render with -->
|
|
57
|
+
<!-- spurious spaces. Add @indent="yes" temporarily when debugging. -->
|
|
58
|
+
<xsl:output method="xml" encoding="UTF-8"/>
|
|
59
|
+
|
|
60
|
+
<!-- This variable controls representations of interactive exercises -->
|
|
61
|
+
<!-- built in pretext-assembly.xsl. A PDF is a static format, so we -->
|
|
62
|
+
<!-- use the "standard" PreTeXt exercise versions. -->
|
|
63
|
+
<xsl:variable name="exercise-style" select="'static'"/>
|
|
64
|
+
|
|
65
|
+
<!-- Math will arrive as SVG produced by mathjax_latex(..., 'svg'), -->
|
|
66
|
+
<!-- which absorbs clause-ending punctuation into display math only. -->
|
|
67
|
+
<!-- This override of the adjacent-text-node behavior must match; see -->
|
|
68
|
+
<!-- pretext-epub.xsl for the full discussion. -->
|
|
69
|
+
<xsl:variable name="math.punctuation.include" select="'display'"/>
|
|
70
|
+
|
|
71
|
+
<!-- ############################## -->
|
|
72
|
+
<!-- Incorporate (Meld) Mathematics -->
|
|
73
|
+
<!-- ############################## -->
|
|
74
|
+
|
|
75
|
+
<!-- Mathematics is rendered by MathJax as SVG images, exactly as the -->
|
|
76
|
+
<!-- EPUB conversion does (see pretext-epub.xsl and the epub() -->
|
|
77
|
+
<!-- routine in pretext/lib/pretext.py). The mathjax_latex() -->
|
|
78
|
+
<!-- routine produces a file of pi:math-representations elements, -->
|
|
79
|
+
<!-- passed in here as the $mathfile string parameter by the -->
|
|
80
|
+
<!-- pdf_fo() routine. Absent the parameter (e.g. a bare "-f fo" -->
|
|
81
|
+
<!-- build), mathematics renders as boxed placeholders; see the -->
|
|
82
|
+
<!-- "Mathematics" section below for both. -->
|
|
83
|
+
<xsl:param name="mathfile" select="''"/>
|
|
84
|
+
<xsl:variable name="math-repr" select="document($mathfile)/pi:math-representations"/>
|
|
85
|
+
|
|
86
|
+
<!-- A second file of speech representations of the mathematics, -->
|
|
87
|
+
<!-- by MathJax and the Speech Rule Engine, becomes alternate -->
|
|
88
|
+
<!-- text ("fox:alt-text") on each SVG image, as PDF/UA requires -->
|
|
89
|
+
<!-- of any figure. -->
|
|
90
|
+
<xsl:param name="speechfile" select="''"/>
|
|
91
|
+
<xsl:variable name="speech-repr" select="document($speechfile)/pi:math-representations"/>
|
|
92
|
+
|
|
93
|
+
<!-- ########### -->
|
|
94
|
+
<!-- Page Layout -->
|
|
95
|
+
<!-- ########### -->
|
|
96
|
+
|
|
97
|
+
<!-- Publisher variables for LaTeX output are honored when they map -->
|
|
98
|
+
<!-- cleanly onto page-layout concepts: $font-size arrives with the -->
|
|
99
|
+
<!-- unit attached ("11pt"), ready for use, and $latex-sides selects -->
|
|
100
|
+
<!-- mirrored margins. The raw $latex-page-geometry string is input -->
|
|
101
|
+
<!-- for the LaTeX "geometry" package, so we do not parse it; instead -->
|
|
102
|
+
<!-- we will map the *intent* of such requests as this conversion -->
|
|
103
|
+
<!-- matures. -->
|
|
104
|
+
|
|
105
|
+
<!-- PDF/UA (ISO 14289) requires every font to be embedded, so -->
|
|
106
|
+
<!-- each font family must name a real, available font: a generic -->
|
|
107
|
+
<!-- family (serif, monospace) would fall back to a base-14 PDF -->
|
|
108
|
+
<!-- font, which is never embedded. Each named family must have a -->
|
|
109
|
+
<!-- matching declaration in pretext/fop.xconf. The body is -->
|
|
110
|
+
<!-- Latin Modern Roman and the monospace face Inconsolata; the -->
|
|
111
|
+
<!-- symbol family is "PreTeXt Symbols", the bundled FreeSerif -->
|
|
112
|
+
<!-- subset (see fonts/README.md ), which carries the currency -->
|
|
113
|
+
<!-- signs, primes, geometric end-marks, and dingbats that Latin -->
|
|
114
|
+
<!-- Modern lacks. It is named after the body font on fo:root , -->
|
|
115
|
+
<!-- so FOP falls back to it for any glyph the body font is -->
|
|
116
|
+
<!-- missing, and named outright where a specific symbol is drawn. -->
|
|
117
|
+
<!-- the 12-point optical design is used for a body font size of -->
|
|
118
|
+
<!-- 12pt or more; smaller sizes (and 11pt) use the 10-point face -->
|
|
119
|
+
<xsl:variable name="font-family-main">
|
|
120
|
+
<xsl:choose>
|
|
121
|
+
<xsl:when test="number(substring-before($font-size, 'pt')) >= 12">
|
|
122
|
+
<xsl:text>Latin Modern Roman 12</xsl:text>
|
|
123
|
+
</xsl:when>
|
|
124
|
+
<xsl:otherwise>
|
|
125
|
+
<xsl:text>Latin Modern Roman</xsl:text>
|
|
126
|
+
</xsl:otherwise>
|
|
127
|
+
</xsl:choose>
|
|
128
|
+
</xsl:variable>
|
|
129
|
+
<xsl:variable name="font-family-monospace" select="'Inconsolata'"/>
|
|
130
|
+
<!-- for symbols absent from the main font (e.g. the end-marks) -->
|
|
131
|
+
<xsl:variable name="font-family-symbol" select="'PreTeXt Symbols'"/>
|
|
132
|
+
<!-- a last-resort broad serif (STIX Two Text) for the few -->
|
|
133
|
+
<!-- characters Latin Modern lacks in running text, notably the -->
|
|
134
|
+
<!-- micro sign U+00B5 (the SI "micro" prefix, as in micrometres). -->
|
|
135
|
+
<!-- It is listed *last* on fo:root below. FOP falls back per -->
|
|
136
|
+
<!-- word, so a glyph sitting mid-word cannot be drawn from the -->
|
|
137
|
+
<!-- symbol font while the rest of the word keeps the body font; -->
|
|
138
|
+
<!-- a broad face can set the whole word. This restores coverage -->
|
|
139
|
+
<!-- DejaVu used to give implicitly, before it was dropped. -->
|
|
140
|
+
<xsl:variable name="font-family-broad" select="'STIX Two Text'"/>
|
|
141
|
+
<!-- the <icon> faces, declared in fop.xconf: FontAwesome 5 Solid -->
|
|
142
|
+
<!-- for the "classic" icons, Brands for the Creative Commons marks -->
|
|
143
|
+
<xsl:variable name="font-family-icon" select="'Font Awesome 5 Free Solid'"/>
|
|
144
|
+
<xsl:variable name="font-family-icon-brands" select="'Font Awesome 5 Brands'"/>
|
|
145
|
+
|
|
146
|
+
<!-- US Letter, matching the LaTeX conversion default -->
|
|
147
|
+
<xsl:variable name="page-width" select="'8.5in'"/>
|
|
148
|
+
<xsl:variable name="page-height" select="'11in'"/>
|
|
149
|
+
|
|
150
|
+
<!-- The body text width, in points, matches the LaTeX conversion: -->
|
|
151
|
+
<!-- Bringhurst's measure of 34 times the point size (close to 75 -->
|
|
152
|
+
<!-- characters per line), so 340pt at a 10pt size. A "tabular" -->
|
|
153
|
+
<!-- estimates its natural width in points, then claims that as a -->
|
|
154
|
+
<!-- percentage of this reference (see the table code). -->
|
|
155
|
+
<xsl:variable name="text-width-points" select="34 * number(substring-before($font-size, 'pt'))"/>
|
|
156
|
+
|
|
157
|
+
<!-- The LaTeX "\geometry{...total=...}" centers the text block on -->
|
|
158
|
+
<!-- the page, so the side margins are equal (no binding offset) -->
|
|
159
|
+
<!-- and the block is identical to the LaTeX route. The 8.5in page -->
|
|
160
|
+
<!-- is 612pt wide; the leftover splits evenly between the margins. -->
|
|
161
|
+
<xsl:variable name="margin-side" select="concat((612 - $text-width-points) div 2, 'pt')"/>
|
|
162
|
+
|
|
163
|
+
<!-- The publisher's right-alignment choice: text justified to both -->
|
|
164
|
+
<!-- margins ("flush", the default), or an even word space and a -->
|
|
165
|
+
<!-- ragged right margin. -->
|
|
166
|
+
<xsl:variable name="text-alignment">
|
|
167
|
+
<xsl:choose>
|
|
168
|
+
<xsl:when test="$latex-right-alignment = 'ragged'">
|
|
169
|
+
<xsl:text>start</xsl:text>
|
|
170
|
+
</xsl:when>
|
|
171
|
+
<xsl:otherwise>
|
|
172
|
+
<xsl:text>justify</xsl:text>
|
|
173
|
+
</xsl:otherwise>
|
|
174
|
+
</xsl:choose>
|
|
175
|
+
</xsl:variable>
|
|
176
|
+
|
|
177
|
+
<!-- Page numbers within cross-references, via the publisher's -->
|
|
178
|
+
<!-- "pageref" choice: explicitly "yes" or "no", or else defaulting -->
|
|
179
|
+
<!-- by utility, on for a print PDF (chase a reference by flipping -->
|
|
180
|
+
<!-- pages) and off for an electronic PDF (just follow the link). -->
|
|
181
|
+
<!-- The same logic as the LaTeX conversion. -->
|
|
182
|
+
<xsl:variable name="b-pageref"
|
|
183
|
+
select="($latex-pageref = 'yes') or (($latex-pageref = '') and $b-latex-print)"/>
|
|
184
|
+
|
|
185
|
+
<!-- The publisher's watermark ($watermark-text, with a scale -->
|
|
186
|
+
<!-- factor) becomes light gray text, rotated diagonally and -->
|
|
187
|
+
<!-- centered behind every page's content. The implementation is -->
|
|
188
|
+
<!-- a small SVG image, written as watermark.svg beside the .fo -->
|
|
189
|
+
<!-- file (FOP reads a "data" URI only in base64 form, beyond XSLT -->
|
|
190
|
+
<!-- 1.0), and painted as the background of the body region; a -->
|
|
191
|
+
<!-- background is never content, so the structure tree of the -->
|
|
192
|
+
<!-- tagged PDF is undisturbed. The historical default font is -->
|
|
193
|
+
<!-- 5cm (141.73pt), tamed by the scale factor, exactly as in the -->
|
|
194
|
+
<!-- LaTeX conversion. -->
|
|
195
|
+
<xsl:template name="watermark-attributes">
|
|
196
|
+
<xsl:if test="not($watermark-text = '')">
|
|
197
|
+
<xsl:attribute name="background-image">
|
|
198
|
+
<xsl:text>url('watermark.svg')</xsl:text>
|
|
199
|
+
</xsl:attribute>
|
|
200
|
+
<xsl:attribute name="background-repeat">
|
|
201
|
+
<xsl:text>no-repeat</xsl:text>
|
|
202
|
+
</xsl:attribute>
|
|
203
|
+
<xsl:attribute name="background-position-horizontal">
|
|
204
|
+
<xsl:text>center</xsl:text>
|
|
205
|
+
</xsl:attribute>
|
|
206
|
+
<xsl:attribute name="background-position-vertical">
|
|
207
|
+
<xsl:text>center</xsl:text>
|
|
208
|
+
</xsl:attribute>
|
|
209
|
+
</xsl:if>
|
|
210
|
+
</xsl:template>
|
|
211
|
+
|
|
212
|
+
<!-- The image itself: sized to sit within the body region of the -->
|
|
213
|
+
<!-- default page (6.5in by 9in, expressed in points), the text -->
|
|
214
|
+
<!-- rotated about the center. -->
|
|
215
|
+
<xsl:template name="watermark-image-file">
|
|
216
|
+
<xsl:if test="not($watermark-text = '')">
|
|
217
|
+
<exsl:document href="watermark.svg" method="xml" indent="no">
|
|
218
|
+
<svg:svg width="468pt" height="648pt" viewBox="0 0 468 648">
|
|
219
|
+
<svg:text x="234" y="324"
|
|
220
|
+
font-family="DejaVu Sans"
|
|
221
|
+
font-size="{format-number(141.73 * $watermark-scale, '0.##')}"
|
|
222
|
+
fill="#CCCCCC"
|
|
223
|
+
text-anchor="middle"
|
|
224
|
+
transform="rotate(-45 234 324)">
|
|
225
|
+
<xsl:value-of select="$watermark-text"/>
|
|
226
|
+
</svg:text>
|
|
227
|
+
</svg:svg>
|
|
228
|
+
</exsl:document>
|
|
229
|
+
</xsl:if>
|
|
230
|
+
</xsl:template>
|
|
231
|
+
|
|
232
|
+
<!-- ##### -->
|
|
233
|
+
<!-- Entry -->
|
|
234
|
+
<!-- ##### -->
|
|
235
|
+
|
|
236
|
+
<!-- Deprecation warnings are universal, so issued here on the -->
|
|
237
|
+
<!-- original source, before attention turns to the assembled source. -->
|
|
238
|
+
<!-- The font families are Unicode-capable, and declared, fully -->
|
|
239
|
+
<!-- embedded, in the fop.xconf configuration. -->
|
|
240
|
+
<!-- The document language (via @xml:lang) and the document title (in -->
|
|
241
|
+
<!-- the XMP metadata of fo:declarations) propagate to the PDF, -->
|
|
242
|
+
<!-- where PDF/UA (ISO 14289) and WCAG require them. -->
|
|
243
|
+
<xsl:template match="/">
|
|
244
|
+
<xsl:apply-templates select="$original" mode="generic-warnings"/>
|
|
245
|
+
<xsl:apply-templates select="$original" mode="element-deprecation-warnings"/>
|
|
246
|
+
<xsl:apply-templates select="$original" mode="parameter-deprecation-warnings"/>
|
|
247
|
+
<xsl:call-template name="watermark-image-file"/>
|
|
248
|
+
<!-- The body font-family is a list: the main face, then the symbol -->
|
|
249
|
+
<!-- face. FOP selects per glyph, so any character missing from the -->
|
|
250
|
+
<!-- main font (a currency sign, a prime, a list-marker square) is -->
|
|
251
|
+
<!-- drawn from "PreTeXt Symbols" without any per-character markup. -->
|
|
252
|
+
<fo:root font-family="{$font-family-main}, {$font-family-symbol}, {$font-family-broad}" font-size="{$font-size}" xml:lang="{$document-language}">
|
|
253
|
+
<fo:layout-master-set>
|
|
254
|
+
<fo:simple-page-master master-name="page-odd"
|
|
255
|
+
page-width="{$page-width}"
|
|
256
|
+
page-height="{$page-height}"
|
|
257
|
+
margin-top="1in"
|
|
258
|
+
margin-bottom="0.6in"
|
|
259
|
+
margin-left="{$margin-side}"
|
|
260
|
+
margin-right="{$margin-side}">
|
|
261
|
+
<fo:region-body margin-bottom="0.4in">
|
|
262
|
+
<xsl:call-template name="watermark-attributes"/>
|
|
263
|
+
</fo:region-body>
|
|
264
|
+
<fo:region-after extent="0.4in"/>
|
|
265
|
+
</fo:simple-page-master>
|
|
266
|
+
<fo:simple-page-master master-name="page-even"
|
|
267
|
+
page-width="{$page-width}"
|
|
268
|
+
page-height="{$page-height}"
|
|
269
|
+
margin-top="1in"
|
|
270
|
+
margin-bottom="0.6in"
|
|
271
|
+
margin-left="{$margin-side}"
|
|
272
|
+
margin-right="{$margin-side}">
|
|
273
|
+
<fo:region-body margin-bottom="0.4in">
|
|
274
|
+
<xsl:call-template name="watermark-attributes"/>
|
|
275
|
+
</fo:region-body>
|
|
276
|
+
<fo:region-after extent="0.4in"/>
|
|
277
|
+
</fo:simple-page-master>
|
|
278
|
+
<!-- the pages of a back-of-the-book index set in two columns -->
|
|
279
|
+
<fo:simple-page-master master-name="page-index-odd"
|
|
280
|
+
page-width="{$page-width}"
|
|
281
|
+
page-height="{$page-height}"
|
|
282
|
+
margin-top="1in"
|
|
283
|
+
margin-bottom="0.6in"
|
|
284
|
+
margin-left="{$margin-side}"
|
|
285
|
+
margin-right="{$margin-side}">
|
|
286
|
+
<fo:region-body margin-bottom="0.4in" column-count="2" column-gap="2em">
|
|
287
|
+
<xsl:call-template name="watermark-attributes"/>
|
|
288
|
+
</fo:region-body>
|
|
289
|
+
<fo:region-after extent="0.4in"/>
|
|
290
|
+
</fo:simple-page-master>
|
|
291
|
+
<fo:simple-page-master master-name="page-index-even"
|
|
292
|
+
page-width="{$page-width}"
|
|
293
|
+
page-height="{$page-height}"
|
|
294
|
+
margin-top="1in"
|
|
295
|
+
margin-bottom="0.6in"
|
|
296
|
+
margin-left="{$margin-side}"
|
|
297
|
+
margin-right="{$margin-side}">
|
|
298
|
+
<fo:region-body margin-bottom="0.4in" column-count="2" column-gap="2em">
|
|
299
|
+
<xsl:call-template name="watermark-attributes"/>
|
|
300
|
+
</fo:region-body>
|
|
301
|
+
<fo:region-after extent="0.4in"/>
|
|
302
|
+
</fo:simple-page-master>
|
|
303
|
+
<fo:page-sequence-master master-name="pages">
|
|
304
|
+
<fo:repeatable-page-master-alternatives>
|
|
305
|
+
<fo:conditional-page-master-reference master-reference="page-odd" odd-or-even="odd"/>
|
|
306
|
+
<fo:conditional-page-master-reference master-reference="page-even" odd-or-even="even"/>
|
|
307
|
+
</fo:repeatable-page-master-alternatives>
|
|
308
|
+
</fo:page-sequence-master>
|
|
309
|
+
<fo:page-sequence-master master-name="pages-index">
|
|
310
|
+
<fo:repeatable-page-master-alternatives>
|
|
311
|
+
<fo:conditional-page-master-reference master-reference="page-index-odd" odd-or-even="odd"/>
|
|
312
|
+
<fo:conditional-page-master-reference master-reference="page-index-even" odd-or-even="even"/>
|
|
313
|
+
</fo:repeatable-page-master-alternatives>
|
|
314
|
+
</fo:page-sequence-master>
|
|
315
|
+
</fo:layout-master-set>
|
|
316
|
+
<fo:declarations>
|
|
317
|
+
<x:xmpmeta xmlns:x="adobe:ns:meta/">
|
|
318
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
|
319
|
+
<rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
|
320
|
+
<!-- The XMP specification requires "dc:title" to be a -->
|
|
321
|
+
<!-- language-alternative array, never bare text, and -->
|
|
322
|
+
<!-- PDF/UA validators check the structure (ISO 14289-1, -->
|
|
323
|
+
<!-- clause 7.1). -->
|
|
324
|
+
<dc:title>
|
|
325
|
+
<rdf:Alt>
|
|
326
|
+
<rdf:li xml:lang="x-default">
|
|
327
|
+
<xsl:variable name="document-title">
|
|
328
|
+
<xsl:apply-templates select="$document-root" mode="title-simple"/>
|
|
329
|
+
</xsl:variable>
|
|
330
|
+
<xsl:value-of select="normalize-space($document-title)"/>
|
|
331
|
+
</rdf:li>
|
|
332
|
+
</rdf:Alt>
|
|
333
|
+
</dc:title>
|
|
334
|
+
</rdf:Description>
|
|
335
|
+
</rdf:RDF>
|
|
336
|
+
</x:xmpmeta>
|
|
337
|
+
<xsl:call-template name="math-cross-reference-destinations"/>
|
|
338
|
+
</fo:declarations>
|
|
339
|
+
<fo:bookmark-tree>
|
|
340
|
+
<xsl:apply-templates select="$document-root/*" mode="bookmark"/>
|
|
341
|
+
</fo:bookmark-tree>
|
|
342
|
+
<!-- A back-of-the-book index earns a page sequence of its -->
|
|
343
|
+
<!-- own, with a two-column body region, so the document -->
|
|
344
|
+
<!-- partitions around it (page numbering just continues), and -->
|
|
345
|
+
<!-- back matter following the index gets a third, ordinary -->
|
|
346
|
+
<!-- sequence. Without an index, one sequence carries all. -->
|
|
347
|
+
<xsl:variable name="the-index" select="$document-root/backmatter/index[index-list]"/>
|
|
348
|
+
<xsl:choose>
|
|
349
|
+
<xsl:when test="$the-index">
|
|
350
|
+
<xsl:call-template name="content-page-sequence">
|
|
351
|
+
<xsl:with-param name="master" select="'pages'"/>
|
|
352
|
+
<xsl:with-param name="content">
|
|
353
|
+
<xsl:apply-templates select="$document-root" mode="document-title-block"/>
|
|
354
|
+
<xsl:apply-templates select="$document-root/*[not(self::backmatter)]"/>
|
|
355
|
+
<xsl:apply-templates select="$document-root/backmatter/*[not(self::index[index-list]) and not(preceding-sibling::index[index-list])]"/>
|
|
356
|
+
</xsl:with-param>
|
|
357
|
+
</xsl:call-template>
|
|
358
|
+
<xsl:call-template name="content-page-sequence">
|
|
359
|
+
<xsl:with-param name="master" select="'pages-index'"/>
|
|
360
|
+
<xsl:with-param name="content">
|
|
361
|
+
<xsl:apply-templates select="$the-index" mode="division-heading"/>
|
|
362
|
+
<xsl:apply-templates select="$the-index/*[not(self::title)]"/>
|
|
363
|
+
</xsl:with-param>
|
|
364
|
+
</xsl:call-template>
|
|
365
|
+
<xsl:if test="$the-index/following-sibling::*">
|
|
366
|
+
<xsl:call-template name="content-page-sequence">
|
|
367
|
+
<xsl:with-param name="master" select="'pages'"/>
|
|
368
|
+
<xsl:with-param name="content">
|
|
369
|
+
<xsl:apply-templates select="$the-index/following-sibling::*"/>
|
|
370
|
+
</xsl:with-param>
|
|
371
|
+
</xsl:call-template>
|
|
372
|
+
</xsl:if>
|
|
373
|
+
</xsl:when>
|
|
374
|
+
<xsl:otherwise>
|
|
375
|
+
<xsl:call-template name="content-page-sequence">
|
|
376
|
+
<xsl:with-param name="master" select="'pages'"/>
|
|
377
|
+
<xsl:with-param name="content">
|
|
378
|
+
<xsl:apply-templates select="$document-root"/>
|
|
379
|
+
</xsl:with-param>
|
|
380
|
+
</xsl:call-template>
|
|
381
|
+
</xsl:otherwise>
|
|
382
|
+
</xsl:choose>
|
|
383
|
+
</fo:root>
|
|
384
|
+
</xsl:template>
|
|
385
|
+
|
|
386
|
+
<!-- One page sequence: the folio in the footer, the footnote -->
|
|
387
|
+
<!-- separator rule, and the supplied content in the body. -->
|
|
388
|
+
<xsl:template name="content-page-sequence">
|
|
389
|
+
<xsl:param name="master"/>
|
|
390
|
+
<xsl:param name="content"/>
|
|
391
|
+
<fo:page-sequence master-reference="{$master}">
|
|
392
|
+
<fo:static-content flow-name="xsl-region-after">
|
|
393
|
+
<fo:block text-align="center" font-size="90%">
|
|
394
|
+
<fo:page-number/>
|
|
395
|
+
</fo:block>
|
|
396
|
+
</fo:static-content>
|
|
397
|
+
<fo:static-content flow-name="xsl-footnote-separator">
|
|
398
|
+
<fo:block end-indent="70%" space-before="4pt" space-after="4pt">
|
|
399
|
+
<fo:leader leader-pattern="rule" leader-length="100%" rule-thickness="0.5pt"/>
|
|
400
|
+
</fo:block>
|
|
401
|
+
</fo:static-content>
|
|
402
|
+
<fo:flow flow-name="xsl-region-body">
|
|
403
|
+
<xsl:copy-of select="$content"/>
|
|
404
|
+
</fo:flow>
|
|
405
|
+
</fo:page-sequence>
|
|
406
|
+
</xsl:template>
|
|
407
|
+
|
|
408
|
+
<!-- ############# -->
|
|
409
|
+
<!-- PDF Bookmarks -->
|
|
410
|
+
<!-- ############# -->
|
|
411
|
+
|
|
412
|
+
<!-- The bookmark tree (the PDF "outline") mirrors the division -->
|
|
413
|
+
<!-- structure, each entry an internal link to its heading's @id. -->
|
|
414
|
+
<!-- Titles must be plain text, so the simple/plain title modes. -->
|
|
415
|
+
<xsl:template match="*" mode="bookmark"/>
|
|
416
|
+
|
|
417
|
+
<!-- pure containers: recurse to the divisions inside -->
|
|
418
|
+
<xsl:template match="frontmatter|backmatter" mode="bookmark">
|
|
419
|
+
<xsl:apply-templates select="*" mode="bookmark"/>
|
|
420
|
+
</xsl:template>
|
|
421
|
+
|
|
422
|
+
<xsl:template match="chapter|section|subsection|subsubsection|appendix|exercises|worksheet|handout|reading-questions|solutions|references|glossary|preface|acknowledgement|foreword|dedication|biography|colophon|index" mode="bookmark">
|
|
423
|
+
<fo:bookmark>
|
|
424
|
+
<xsl:attribute name="internal-destination">
|
|
425
|
+
<xsl:apply-templates select="." mode="unique-id"/>
|
|
426
|
+
</xsl:attribute>
|
|
427
|
+
<fo:bookmark-title>
|
|
428
|
+
<xsl:variable name="the-number">
|
|
429
|
+
<xsl:apply-templates select="." mode="number"/>
|
|
430
|
+
</xsl:variable>
|
|
431
|
+
<xsl:if test="not($the-number = '')">
|
|
432
|
+
<xsl:value-of select="$the-number"/>
|
|
433
|
+
<xsl:text> </xsl:text>
|
|
434
|
+
</xsl:if>
|
|
435
|
+
<xsl:variable name="the-title">
|
|
436
|
+
<xsl:apply-templates select="." mode="title-simple"/>
|
|
437
|
+
</xsl:variable>
|
|
438
|
+
<xsl:value-of select="normalize-space($the-title)"/>
|
|
439
|
+
</fo:bookmark-title>
|
|
440
|
+
<xsl:apply-templates select="*" mode="bookmark"/>
|
|
441
|
+
</fo:bookmark>
|
|
442
|
+
</xsl:template>
|
|
443
|
+
|
|
444
|
+
<!-- ###################### -->
|
|
445
|
+
<!-- Front and Back Matter -->
|
|
446
|
+
<!-- ###################### -->
|
|
447
|
+
|
|
448
|
+
<!-- The "frontmatter" flows: the title page, an abstract, and any -->
|
|
449
|
+
<!-- front divisions (preface, foreword, ...) in order. The -->
|
|
450
|
+
<!-- "bibinfo" is pure metadata, consumed from the $bibinfo -->
|
|
451
|
+
<!-- variable by the title page. -->
|
|
452
|
+
<xsl:template match="frontmatter">
|
|
453
|
+
<xsl:apply-templates select="*"/>
|
|
454
|
+
</xsl:template>
|
|
455
|
+
|
|
456
|
+
<xsl:template match="bibinfo"/>
|
|
457
|
+
|
|
458
|
+
<!-- The "titlepage-items" element is the hook requesting the -->
|
|
459
|
+
<!-- default sequence: authors and editors, credits, the date. -->
|
|
460
|
+
<!-- (The document title itself renders at the document root.) -->
|
|
461
|
+
<xsl:template match="titlepage">
|
|
462
|
+
<xsl:apply-templates select="titlepage-items"/>
|
|
463
|
+
</xsl:template>
|
|
464
|
+
|
|
465
|
+
<xsl:template match="titlepage-items">
|
|
466
|
+
<xsl:apply-templates select="$bibinfo/author|$bibinfo/editor" mode="full-info"/>
|
|
467
|
+
<xsl:apply-templates select="$bibinfo/credit[title]"/>
|
|
468
|
+
<xsl:apply-templates select="$bibinfo/date" mode="titlepage-date"/>
|
|
469
|
+
</xsl:template>
|
|
470
|
+
|
|
471
|
+
<!-- One author or editor, centered: name, affiliation, -->
|
|
472
|
+
<!-- electronic address, support acknowledgement. -->
|
|
473
|
+
<xsl:template match="author|editor" mode="full-info">
|
|
474
|
+
<fo:block text-align="center" space-after="1em">
|
|
475
|
+
<fo:block font-size="120%">
|
|
476
|
+
<xsl:apply-templates select="personname"/>
|
|
477
|
+
<xsl:if test="self::editor">
|
|
478
|
+
<xsl:text>, </xsl:text>
|
|
479
|
+
<xsl:apply-templates select="." mode="type-name"/>
|
|
480
|
+
</xsl:if>
|
|
481
|
+
</fo:block>
|
|
482
|
+
<xsl:apply-templates select="affiliation"/>
|
|
483
|
+
<xsl:if test="email">
|
|
484
|
+
<fo:block>
|
|
485
|
+
<xsl:apply-templates select="email"/>
|
|
486
|
+
</fo:block>
|
|
487
|
+
</xsl:if>
|
|
488
|
+
<xsl:if test="support">
|
|
489
|
+
<fo:block font-size="90%">
|
|
490
|
+
<xsl:apply-templates select="support/node()"/>
|
|
491
|
+
</fo:block>
|
|
492
|
+
</xsl:if>
|
|
493
|
+
</fo:block>
|
|
494
|
+
</xsl:template>
|
|
495
|
+
|
|
496
|
+
<xsl:template match="personname">
|
|
497
|
+
<xsl:apply-templates/>
|
|
498
|
+
</xsl:template>
|
|
499
|
+
|
|
500
|
+
<xsl:template match="affiliation">
|
|
501
|
+
<xsl:apply-templates select="department|institution|location"/>
|
|
502
|
+
</xsl:template>
|
|
503
|
+
|
|
504
|
+
<!-- each is a line, or authored "line"s, of the address block -->
|
|
505
|
+
<xsl:template match="department|institution|location">
|
|
506
|
+
<xsl:choose>
|
|
507
|
+
<xsl:when test="line">
|
|
508
|
+
<xsl:apply-templates select="line"/>
|
|
509
|
+
</xsl:when>
|
|
510
|
+
<xsl:otherwise>
|
|
511
|
+
<fo:block>
|
|
512
|
+
<xsl:apply-templates/>
|
|
513
|
+
</fo:block>
|
|
514
|
+
</xsl:otherwise>
|
|
515
|
+
</xsl:choose>
|
|
516
|
+
</xsl:template>
|
|
517
|
+
|
|
518
|
+
<!-- A "credit" is a lesser contribution, with a title -->
|
|
519
|
+
<xsl:template match="bibinfo/credit[title]">
|
|
520
|
+
<fo:block text-align="center" space-after="1em">
|
|
521
|
+
<fo:block font-style="italic">
|
|
522
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
523
|
+
</fo:block>
|
|
524
|
+
<xsl:apply-templates select="author" mode="full-info"/>
|
|
525
|
+
</fo:block>
|
|
526
|
+
</xsl:template>
|
|
527
|
+
|
|
528
|
+
<xsl:template match="bibinfo/date" mode="titlepage-date">
|
|
529
|
+
<fo:block text-align="center" space-after="1em">
|
|
530
|
+
<xsl:apply-templates/>
|
|
531
|
+
</fo:block>
|
|
532
|
+
</xsl:template>
|
|
533
|
+
|
|
534
|
+
<!-- The "abstract", indented, with a run-in localized heading. -->
|
|
535
|
+
<xsl:template match="abstract">
|
|
536
|
+
<fo:block margin-left="2.5em" margin-right="2.5em" space-before="1em" space-after="1em">
|
|
537
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
538
|
+
<xsl:variable name="heading">
|
|
539
|
+
<fo:inline font-weight="bold" font-style="normal">
|
|
540
|
+
<xsl:apply-templates select="." mode="type-name"/>
|
|
541
|
+
<xsl:text>.</xsl:text>
|
|
542
|
+
</fo:inline>
|
|
543
|
+
<xsl:text> </xsl:text>
|
|
544
|
+
</xsl:variable>
|
|
545
|
+
<xsl:call-template name="heading-then-content">
|
|
546
|
+
<xsl:with-param name="heading" select="$heading"/>
|
|
547
|
+
</xsl:call-template>
|
|
548
|
+
</fo:block>
|
|
549
|
+
</xsl:template>
|
|
550
|
+
|
|
551
|
+
<!-- The "backmatter" also just flows -->
|
|
552
|
+
<xsl:template match="backmatter">
|
|
553
|
+
<xsl:apply-templates select="*"/>
|
|
554
|
+
</xsl:template>
|
|
555
|
+
|
|
556
|
+
<!-- ##################### -->
|
|
557
|
+
<!-- Traditional Divisions -->
|
|
558
|
+
<!-- ##################### -->
|
|
559
|
+
|
|
560
|
+
<!-- The traditional divisions: titled headings, then a recursion -->
|
|
561
|
+
<!-- through the contents. Numbers, localized type names, and -->
|
|
562
|
+
<!-- titles all come from the machinery of pretext-common.xsl. -->
|
|
563
|
+
<!-- Specialized divisions, and front and back matter, come later. -->
|
|
564
|
+
|
|
565
|
+
<!-- The document root. A real title page is far in the future, -->
|
|
566
|
+
<!-- so the document title renders as a large, centered heading. -->
|
|
567
|
+
<!-- The @role attributes here and below become PDF structure -->
|
|
568
|
+
<!-- tags (H1, H2, ...) in FOP's Tagged PDF output, the heading -->
|
|
569
|
+
<!-- outline PDF/UA and WCAG call for; division nesting means -->
|
|
570
|
+
<!-- levels are never skipped. -->
|
|
571
|
+
<xsl:template match="article|book">
|
|
572
|
+
<xsl:apply-templates select="." mode="document-title-block"/>
|
|
573
|
+
<xsl:apply-templates/>
|
|
574
|
+
</xsl:template>
|
|
575
|
+
|
|
576
|
+
<!-- factored out, so the partitioned page sequences of a -->
|
|
577
|
+
<!-- document with a two-column index can also lead with -->
|
|
578
|
+
<!-- the document title -->
|
|
579
|
+
<xsl:template match="article|book" mode="document-title-block">
|
|
580
|
+
<fo:block font-size="200%"
|
|
581
|
+
font-weight="bold"
|
|
582
|
+
text-align="center"
|
|
583
|
+
space-after="2em"
|
|
584
|
+
role="H1">
|
|
585
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
586
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
587
|
+
</fo:block>
|
|
588
|
+
</xsl:template>
|
|
589
|
+
|
|
590
|
+
<!-- A heading: optional localized "type-name number", then the -->
|
|
591
|
+
<!-- title. An unnumbered division (perhaps numbering is limited -->
|
|
592
|
+
<!-- by the publisher's numbering level) gets a title-only heading. -->
|
|
593
|
+
<!-- The specialized divisions ("exercises", "references", ...) -->
|
|
594
|
+
<!-- take the very same heading; their specialized *contents* are -->
|
|
595
|
+
<!-- implemented (or not, yet) elsewhere. -->
|
|
596
|
+
<xsl:template match="chapter|section|subsection|subsubsection|appendix|exercises|worksheet|handout|reading-questions|solutions|references|glossary|preface|acknowledgement|foreword|dedication|biography|colophon|index">
|
|
597
|
+
<xsl:apply-templates select="." mode="division-heading"/>
|
|
598
|
+
<xsl:choose>
|
|
599
|
+
<!-- a "solutions" division is empty; its content is mined -->
|
|
600
|
+
<!-- from its scope by the generator in pretext-common.xsl -->
|
|
601
|
+
<xsl:when test="self::solutions">
|
|
602
|
+
<xsl:apply-templates select="idx"/>
|
|
603
|
+
<xsl:apply-templates select="." mode="solutions">
|
|
604
|
+
<xsl:with-param name="heading-level" select="count(ancestor::*[&STRUCTURAL-FILTER;]) + 1"/>
|
|
605
|
+
</xsl:apply-templates>
|
|
606
|
+
</xsl:when>
|
|
607
|
+
<xsl:otherwise>
|
|
608
|
+
<xsl:apply-templates/>
|
|
609
|
+
</xsl:otherwise>
|
|
610
|
+
</xsl:choose>
|
|
611
|
+
<!-- material following a formatted printout begins a fresh page; -->
|
|
612
|
+
<!-- a conclusion, when present, carries that break itself -->
|
|
613
|
+
<xsl:if test="(self::worksheet or self::handout) and $b-latex-worksheet-formatted and not(conclusion)">
|
|
614
|
+
<fo:block break-after="page"/>
|
|
615
|
+
</xsl:if>
|
|
616
|
+
</xsl:template>
|
|
617
|
+
|
|
618
|
+
<!-- The back colophon is centered with side margins like the LaTeX -->
|
|
619
|
+
<!-- "backcolophonstyle": centered "large" bold title, centered body. -->
|
|
620
|
+
<xsl:template match="backmatter/colophon">
|
|
621
|
+
<fo:block start-indent="15%" end-indent="15%" text-align="center">
|
|
622
|
+
<fo:block font-size="109%"
|
|
623
|
+
font-weight="bold"
|
|
624
|
+
space-before="2.5em"
|
|
625
|
+
space-after="1em"
|
|
626
|
+
keep-with-next.within-page="always"
|
|
627
|
+
role="H{count(ancestor::*[&STRUCTURAL-FILTER;]) + 1}">
|
|
628
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
629
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
630
|
+
</fo:block>
|
|
631
|
+
<xsl:apply-templates>
|
|
632
|
+
<xsl:with-param name="alignment" select="'center'"/>
|
|
633
|
+
</xsl:apply-templates>
|
|
634
|
+
</fo:block>
|
|
635
|
+
</xsl:template>
|
|
636
|
+
|
|
637
|
+
<!-- The heading of a division, factored out so the two-column -->
|
|
638
|
+
<!-- index (its own page sequence) can reuse it. Shape and sizes -->
|
|
639
|
+
<!-- follow the LaTeX conversion's "titlesec" styling: "part" and -->
|
|
640
|
+
<!-- "chapter" use a "display" shape, the type-name and number on -->
|
|
641
|
+
<!-- their own line above the title (centered for a "part"), while -->
|
|
642
|
+
<!-- "section" down to "paragraph" level use a "hang" shape, the -->
|
|
643
|
+
<!-- number run into the title on one line, with no type-name. -->
|
|
644
|
+
<xsl:template match="*" mode="division-heading">
|
|
645
|
+
<xsl:variable name="level">
|
|
646
|
+
<xsl:apply-templates select="." mode="division-name"/>
|
|
647
|
+
</xsl:variable>
|
|
648
|
+
<xsl:variable name="the-number">
|
|
649
|
+
<xsl:apply-templates select="." mode="number"/>
|
|
650
|
+
</xsl:variable>
|
|
651
|
+
<xsl:variable name="page-break">
|
|
652
|
+
<xsl:apply-templates select="." mode="division-break"/>
|
|
653
|
+
</xsl:variable>
|
|
654
|
+
<xsl:variable name="hN" select="count(ancestor::*[&STRUCTURAL-FILTER;]) + 1"/>
|
|
655
|
+
<xsl:choose>
|
|
656
|
+
<!-- "display" shape: "part" and "chapter" -->
|
|
657
|
+
<xsl:when test="($level = 'part') or ($level = 'chapter')">
|
|
658
|
+
<!-- "part" is grander and centered, its label at title size -->
|
|
659
|
+
<xsl:variable name="label-size">
|
|
660
|
+
<xsl:choose>
|
|
661
|
+
<xsl:when test="$level = 'part'">227%</xsl:when>
|
|
662
|
+
<xsl:otherwise>182%</xsl:otherwise>
|
|
663
|
+
</xsl:choose>
|
|
664
|
+
</xsl:variable>
|
|
665
|
+
<xsl:variable name="label-gap">
|
|
666
|
+
<xsl:choose>
|
|
667
|
+
<xsl:when test="$level = 'part'">30pt</xsl:when>
|
|
668
|
+
<xsl:otherwise>20pt</xsl:otherwise>
|
|
669
|
+
</xsl:choose>
|
|
670
|
+
</xsl:variable>
|
|
671
|
+
<fo:block font-weight="bold"
|
|
672
|
+
space-before="50pt"
|
|
673
|
+
space-after="40pt"
|
|
674
|
+
keep-with-next.within-page="always"
|
|
675
|
+
role="H{$hN}">
|
|
676
|
+
<xsl:if test="$level = 'part'">
|
|
677
|
+
<xsl:attribute name="text-align">center</xsl:attribute>
|
|
678
|
+
</xsl:if>
|
|
679
|
+
<xsl:if test="not($page-break = '')">
|
|
680
|
+
<xsl:attribute name="break-before">
|
|
681
|
+
<xsl:value-of select="$page-break"/>
|
|
682
|
+
</xsl:attribute>
|
|
683
|
+
</xsl:if>
|
|
684
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
685
|
+
<!-- "Type N" on its own line, dropped when numberless -->
|
|
686
|
+
<xsl:if test="not($the-number = '')">
|
|
687
|
+
<fo:block font-size="{$label-size}" space-after="{$label-gap}">
|
|
688
|
+
<xsl:apply-templates select="." mode="type-name"/>
|
|
689
|
+
<xsl:text> </xsl:text>
|
|
690
|
+
<xsl:value-of select="$the-number"/>
|
|
691
|
+
</fo:block>
|
|
692
|
+
</xsl:if>
|
|
693
|
+
<fo:block font-size="227%">
|
|
694
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
695
|
+
</fo:block>
|
|
696
|
+
</fo:block>
|
|
697
|
+
</xsl:when>
|
|
698
|
+
<!-- "hang" shape: "section" through "paragraph" level -->
|
|
699
|
+
<xsl:otherwise>
|
|
700
|
+
<xsl:variable name="hang-size">
|
|
701
|
+
<xsl:choose>
|
|
702
|
+
<xsl:when test="$level = 'section'">127%</xsl:when>
|
|
703
|
+
<xsl:when test="$level = 'subsection'">109%</xsl:when>
|
|
704
|
+
<xsl:otherwise>100%</xsl:otherwise>
|
|
705
|
+
</xsl:choose>
|
|
706
|
+
</xsl:variable>
|
|
707
|
+
<xsl:variable name="gap-before">
|
|
708
|
+
<xsl:choose>
|
|
709
|
+
<xsl:when test="$level = 'section'">1.75em</xsl:when>
|
|
710
|
+
<xsl:otherwise>1.6em</xsl:otherwise>
|
|
711
|
+
</xsl:choose>
|
|
712
|
+
</xsl:variable>
|
|
713
|
+
<xsl:variable name="gap-after">
|
|
714
|
+
<xsl:choose>
|
|
715
|
+
<xsl:when test="$level = 'section'">1.15em</xsl:when>
|
|
716
|
+
<xsl:when test="$level = 'paragraph'">1.5em</xsl:when>
|
|
717
|
+
<xsl:otherwise>0.75em</xsl:otherwise>
|
|
718
|
+
</xsl:choose>
|
|
719
|
+
</xsl:variable>
|
|
720
|
+
<fo:block font-size="{$hang-size}"
|
|
721
|
+
font-weight="bold"
|
|
722
|
+
space-before="{$gap-before}"
|
|
723
|
+
space-after="{$gap-after}"
|
|
724
|
+
keep-with-next.within-page="always"
|
|
725
|
+
role="H{$hN}">
|
|
726
|
+
<xsl:if test="not($page-break = '')">
|
|
727
|
+
<xsl:attribute name="break-before">
|
|
728
|
+
<xsl:value-of select="$page-break"/>
|
|
729
|
+
</xsl:attribute>
|
|
730
|
+
</xsl:if>
|
|
731
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
732
|
+
<xsl:if test="not($the-number = '')">
|
|
733
|
+
<xsl:value-of select="$the-number"/>
|
|
734
|
+
<xsl:text> </xsl:text>
|
|
735
|
+
</xsl:if>
|
|
736
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
737
|
+
</fo:block>
|
|
738
|
+
</xsl:otherwise>
|
|
739
|
+
</xsl:choose>
|
|
740
|
+
</xsl:template>
|
|
741
|
+
|
|
742
|
+
<!-- The page break, if any, opening a division. A chapter-level -->
|
|
743
|
+
<!-- division of a book begins a fresh page: the odd (recto) page -->
|
|
744
|
+
<!-- of a spread for a two-sided layout, and also for one-sided -->
|
|
745
|
+
<!-- when the publisher elects "open-odd" pagination to match a -->
|
|
746
|
+
<!-- two-sided copy page-for-page. (The publisher's "skip-pages" -->
|
|
747
|
+
<!-- flavor of open-odd asks for a *omitted* page number instead of -->
|
|
748
|
+
<!-- a blank page, which a single XSL-FO page-sequence cannot -->
|
|
749
|
+
<!-- express; it degrades to the blank page.) And a formatted -->
|
|
750
|
+
<!-- printout (worksheet, handout) occupies pages of its own. -->
|
|
751
|
+
<xsl:template match="*" mode="division-break">
|
|
752
|
+
<xsl:choose>
|
|
753
|
+
<xsl:when test="parent::book or parent::part or (ancestor::book and (parent::frontmatter or parent::backmatter))">
|
|
754
|
+
<xsl:choose>
|
|
755
|
+
<xsl:when test="$b-latex-two-sides or not($latex-open-odd = 'no')">
|
|
756
|
+
<xsl:text>odd-page</xsl:text>
|
|
757
|
+
</xsl:when>
|
|
758
|
+
<xsl:otherwise>
|
|
759
|
+
<xsl:text>page</xsl:text>
|
|
760
|
+
</xsl:otherwise>
|
|
761
|
+
</xsl:choose>
|
|
762
|
+
</xsl:when>
|
|
763
|
+
<!-- the publisher names this division for a forced break -->
|
|
764
|
+
<xsl:when test="@xml:id = str:tokenize($latex-pagebreaks-string)">
|
|
765
|
+
<xsl:text>page</xsl:text>
|
|
766
|
+
</xsl:when>
|
|
767
|
+
<xsl:when test="(self::worksheet or self::handout) and $b-latex-worksheet-formatted">
|
|
768
|
+
<xsl:text>page</xsl:text>
|
|
769
|
+
</xsl:when>
|
|
770
|
+
</xsl:choose>
|
|
771
|
+
</xsl:template>
|
|
772
|
+
|
|
773
|
+
<!-- The publisher's "insertions" entries name elements, by their -->
|
|
774
|
+
<!-- @xml:id, that should begin a fresh page, a tool for the final -->
|
|
775
|
+
<!-- massage of a print run. An empty block carries the break, so -->
|
|
776
|
+
<!-- this hook works wherever block content is legal; it is -->
|
|
777
|
+
<!-- consulted by the same sort of elements as honor a request in -->
|
|
778
|
+
<!-- the LaTeX conversion (divisions just above, via the heading's -->
|
|
779
|
+
<!-- own break attribute). -->
|
|
780
|
+
<xsl:template match="*" mode="forced-pagebreak">
|
|
781
|
+
<xsl:if test="@xml:id = str:tokenize($latex-pagebreaks-string)">
|
|
782
|
+
<fo:block break-after="page"/>
|
|
783
|
+
</xsl:if>
|
|
784
|
+
</xsl:template>
|
|
785
|
+
|
|
786
|
+
<!-- A worksheet or handout "page" is a pagination request, -->
|
|
787
|
+
<!-- honored whenever the printout is formatted as such. -->
|
|
788
|
+
<xsl:template match="worksheet/page|handout/page">
|
|
789
|
+
<fo:block>
|
|
790
|
+
<xsl:if test="$b-latex-worksheet-formatted and preceding-sibling::page">
|
|
791
|
+
<xsl:attribute name="break-before">
|
|
792
|
+
<xsl:text>page</xsl:text>
|
|
793
|
+
</xsl:attribute>
|
|
794
|
+
</xsl:if>
|
|
795
|
+
<xsl:apply-templates select="*"/>
|
|
796
|
+
</fo:block>
|
|
797
|
+
</xsl:template>
|
|
798
|
+
|
|
799
|
+
<!-- A "headnote" introduces a glossary or a structured -->
|
|
800
|
+
<!-- bibliography with explanatory prose; contents just flow. -->
|
|
801
|
+
<xsl:template match="headnote">
|
|
802
|
+
<xsl:apply-templates select="*"/>
|
|
803
|
+
</xsl:template>
|
|
804
|
+
|
|
805
|
+
<!-- An "introduction" or "conclusion" of a division is mostly a -->
|
|
806
|
+
<!-- transparent container, but any title runs in, bold, to the -->
|
|
807
|
+
<!-- leading paragraph. -->
|
|
808
|
+
<!-- A task-structured block passes its heading the same way. -->
|
|
809
|
+
<xsl:template match="introduction|conclusion">
|
|
810
|
+
<xsl:param name="run-in-heading"/>
|
|
811
|
+
<xsl:choose>
|
|
812
|
+
<xsl:when test="title">
|
|
813
|
+
<fo:block space-before="1em" space-after="1em">
|
|
814
|
+
<xsl:variable name="heading">
|
|
815
|
+
<fo:inline font-weight="bold" font-style="normal">
|
|
816
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
817
|
+
</fo:inline>
|
|
818
|
+
<xsl:text> </xsl:text>
|
|
819
|
+
</xsl:variable>
|
|
820
|
+
<xsl:call-template name="heading-then-content">
|
|
821
|
+
<xsl:with-param name="heading" select="$heading"/>
|
|
822
|
+
</xsl:call-template>
|
|
823
|
+
</fo:block>
|
|
824
|
+
</xsl:when>
|
|
825
|
+
<xsl:when test="$run-in-heading">
|
|
826
|
+
<xsl:call-template name="heading-then-content">
|
|
827
|
+
<xsl:with-param name="heading" select="$run-in-heading"/>
|
|
828
|
+
</xsl:call-template>
|
|
829
|
+
</xsl:when>
|
|
830
|
+
<xsl:otherwise>
|
|
831
|
+
<xsl:apply-templates select="*"/>
|
|
832
|
+
</xsl:otherwise>
|
|
833
|
+
</xsl:choose>
|
|
834
|
+
</xsl:template>
|
|
835
|
+
|
|
836
|
+
<!-- A worksheet or handout conclusion is pinned to the foot of -->
|
|
837
|
+
<!-- the last page: an overestimated, fully shrinkable space -->
|
|
838
|
+
<!-- overflows the page, and FOP (which shrinks but never grows -->
|
|
839
|
+
<!-- a space) pulls it back to the slack. Else it simply flows. -->
|
|
840
|
+
<xsl:template match="worksheet/conclusion|handout/conclusion">
|
|
841
|
+
<xsl:choose>
|
|
842
|
+
<xsl:when test="$b-latex-worksheet-formatted">
|
|
843
|
+
<!-- "break-after" here, rather than a trailing empty block -->
|
|
844
|
+
<!-- in the division, so a conclusion that fills the page -->
|
|
845
|
+
<!-- does not spill the break onto a blank page -->
|
|
846
|
+
<fo:block space-before.minimum="0pt"
|
|
847
|
+
space-before.optimum="1000pt"
|
|
848
|
+
space-before.maximum="1000pt"
|
|
849
|
+
space-before.conditionality="discard"
|
|
850
|
+
break-after="page">
|
|
851
|
+
<xsl:apply-templates select="*"/>
|
|
852
|
+
</fo:block>
|
|
853
|
+
</xsl:when>
|
|
854
|
+
<xsl:otherwise>
|
|
855
|
+
<xsl:apply-templates select="*"/>
|
|
856
|
+
</xsl:otherwise>
|
|
857
|
+
</xsl:choose>
|
|
858
|
+
</xsl:template>
|
|
859
|
+
|
|
860
|
+
<!-- A "paragraphs" is the lightweight, unnumbered division: just -->
|
|
861
|
+
<!-- its title, bold, run in to the leading paragraph (exactly -->
|
|
862
|
+
<!-- the LaTeX treatment). -->
|
|
863
|
+
<xsl:template match="paragraphs">
|
|
864
|
+
<xsl:apply-templates select="." mode="forced-pagebreak"/>
|
|
865
|
+
<fo:block space-before="1em" space-after="1em">
|
|
866
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
867
|
+
<xsl:variable name="heading">
|
|
868
|
+
<fo:inline font-weight="bold" font-style="normal">
|
|
869
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
870
|
+
</fo:inline>
|
|
871
|
+
<xsl:text> </xsl:text>
|
|
872
|
+
</xsl:variable>
|
|
873
|
+
<xsl:call-template name="heading-then-content">
|
|
874
|
+
<xsl:with-param name="heading" select="$heading"/>
|
|
875
|
+
</xsl:call-template>
|
|
876
|
+
</fo:block>
|
|
877
|
+
</xsl:template>
|
|
878
|
+
|
|
879
|
+
<!-- A glossary item ("gi") reads as a description list entry: -->
|
|
880
|
+
<!-- its title, bold, run in to the explanation. -->
|
|
881
|
+
<xsl:template match="gi">
|
|
882
|
+
<fo:block space-after="0.5em">
|
|
883
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
884
|
+
<xsl:variable name="heading">
|
|
885
|
+
<fo:inline font-weight="bold" font-style="normal">
|
|
886
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
887
|
+
</fo:inline>
|
|
888
|
+
<xsl:text> </xsl:text>
|
|
889
|
+
</xsl:variable>
|
|
890
|
+
<xsl:call-template name="heading-then-content">
|
|
891
|
+
<xsl:with-param name="heading" select="$heading"/>
|
|
892
|
+
</xsl:call-template>
|
|
893
|
+
</fo:block>
|
|
894
|
+
</xsl:template>
|
|
895
|
+
|
|
896
|
+
<!-- A "title" is consumed by modal templates reached from the -->
|
|
897
|
+
<!-- parent element, and is never traversed as content, so it is -->
|
|
898
|
+
<!-- killed in the default mode. Likewise the other metadata: -->
|
|
899
|
+
<!-- "notation" and image descriptions render elsewhere (or not -->
|
|
900
|
+
<!-- yet), never as in-place content. -->
|
|
901
|
+
<xsl:template match="title|subtitle|shorttitle|caption|plaintitle|notation|shortdescription|description|creator"/>
|
|
902
|
+
|
|
903
|
+
<!-- An "idx" is invisible at its location, but the location is -->
|
|
904
|
+
<!-- the whole point: an empty wrapper carries an id, the target -->
|
|
905
|
+
<!-- of the page-number locators of the generated index. Killed -->
|
|
906
|
+
<!-- inside a title, which is rendered repeatedly (the heading, -->
|
|
907
|
+
<!-- the bookmark outline), where the ids would then duplicate. -->
|
|
908
|
+
<xsl:template match="idx">
|
|
909
|
+
<fo:wrapper>
|
|
910
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
911
|
+
</fo:wrapper>
|
|
912
|
+
</xsl:template>
|
|
913
|
+
|
|
914
|
+
<xsl:template match="idx[ancestor::title or ancestor::subtitle or ancestor::shorttitle]"/>
|
|
915
|
+
|
|
916
|
+
<!-- The pieces of an "idx" are processed by the index-construction -->
|
|
917
|
+
<!-- machinery of pretext-common.xsl, which expects the contents to -->
|
|
918
|
+
<!-- pass through (the XSLT built-in rules); the coverage harness -->
|
|
919
|
+
<!-- would otherwise swallow them. -->
|
|
920
|
+
<xsl:template match="idx/h|idx/see|idx/seealso">
|
|
921
|
+
<xsl:apply-templates/>
|
|
922
|
+
</xsl:template>
|
|
923
|
+
|
|
924
|
+
<!-- The "type-name" machinery of pretext-common.xsl applies the -->
|
|
925
|
+
<!-- matching "rename" of an author's "docinfo", expecting its -->
|
|
926
|
+
<!-- text to pass through; the coverage harness would otherwise -->
|
|
927
|
+
<!-- swallow it, and every renamed type would go blank. -->
|
|
928
|
+
<xsl:template match="docinfo/rename">
|
|
929
|
+
<xsl:apply-templates/>
|
|
930
|
+
</xsl:template>
|
|
931
|
+
|
|
932
|
+
<!-- ########## -->
|
|
933
|
+
<!-- Paragraphs -->
|
|
934
|
+
<!-- ########## -->
|
|
935
|
+
|
|
936
|
+
<!-- The "run-in-heading" parameter carries the heading of a -->
|
|
937
|
+
<!-- surrounding block (theorem, proof, ...) for a paragraph that -->
|
|
938
|
+
<!-- leads off that block's content; see "heading-then-content". -->
|
|
939
|
+
<xsl:template match="p">
|
|
940
|
+
<xsl:param name="run-in-heading"/>
|
|
941
|
+
<xsl:param name="trailing-tombstone"/>
|
|
942
|
+
<xsl:param name="alignment" select="$text-alignment"/>
|
|
943
|
+
<xsl:apply-templates select="." mode="forced-pagebreak"/>
|
|
944
|
+
<fo:block text-align="{$alignment}">
|
|
945
|
+
<!-- A new paragraph is set off by indenting its first line -->
|
|
946
|
+
<!-- rather than by vertical space, so consecutive paragraphs -->
|
|
947
|
+
<!-- share the body leading (no "space-after"). Indent a "p" -->
|
|
948
|
+
<!-- exactly when another "p" precedes it among its siblings. -->
|
|
949
|
+
<!-- The opening paragraph of a division or block (after a -->
|
|
950
|
+
<!-- heading, or a figure's "caption") then stays flush, having -->
|
|
951
|
+
<!-- no earlier paragraph to break from, while a paragraph that -->
|
|
952
|
+
<!-- follows an interruption between paragraphs (a figure, a -->
|
|
953
|
+
<!-- list) is the next paragraph in the prose and indents. Using -->
|
|
954
|
+
<!-- "preceding-sibling::p" (not the immediate predecessor) keeps -->
|
|
955
|
+
<!-- an invisible "idx" or "notation" marker between paragraphs -->
|
|
956
|
+
<!-- from masking the earlier one. Text resuming after an -->
|
|
957
|
+
<!-- in-paragraph display stays flush: FOP indents only a -->
|
|
958
|
+
<!-- block's first line, not a line that follows a nested block. -->
|
|
959
|
+
<!-- Bringhurst (The Elements of Typographic Style, 4th ed.) -->
|
|
960
|
+
<!-- makes the case for both. Sec. 2.3.2: "In continuous text -->
|
|
961
|
+
<!-- mark all paragraphs after the first with an indent of at -->
|
|
962
|
+
<!-- least one en" (the 1.5em here, the LaTeX article default, -->
|
|
963
|
+
<!-- exceeds that minimum). Sec. 2.3.1, on the flush opener: -->
|
|
964
|
+
<!-- "The function of a paragraph indent is to mark a pause, -->
|
|
965
|
+
<!-- setting the paragraph apart from what precedes it. If a -->
|
|
966
|
+
<!-- paragraph is preceded by a title or subhead, the indent is -->
|
|
967
|
+
<!-- superfluous and can therefore be omitted, as it is here." -->
|
|
968
|
+
<xsl:if test="preceding-sibling::p">
|
|
969
|
+
<xsl:attribute name="text-indent">
|
|
970
|
+
<xsl:value-of select="$paragraph-indentation"/>
|
|
971
|
+
<xsl:text>em</xsl:text>
|
|
972
|
+
</xsl:attribute>
|
|
973
|
+
</xsl:if>
|
|
974
|
+
<!-- a tombstone arriving from an enclosing PROOF-LIKE rides -->
|
|
975
|
+
<!-- the final line, whose elastic leader needs the line -->
|
|
976
|
+
<!-- justified to push the tombstone to the right margin -->
|
|
977
|
+
<xsl:if test="not(string($trailing-tombstone) = '')">
|
|
978
|
+
<xsl:attribute name="text-align-last">
|
|
979
|
+
<xsl:text>justify</xsl:text>
|
|
980
|
+
</xsl:attribute>
|
|
981
|
+
</xsl:if>
|
|
982
|
+
<!-- a top-level paragraph can enclose a "notation", whose -->
|
|
983
|
+
<!-- generated list then links here, so every "p" carries an -->
|
|
984
|
+
<!-- id (and becomes a cross-reference target generally) -->
|
|
985
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
986
|
+
<xsl:copy-of select="$run-in-heading"/>
|
|
987
|
+
<xsl:apply-templates/>
|
|
988
|
+
<xsl:copy-of select="$trailing-tombstone"/>
|
|
989
|
+
</fo:block>
|
|
990
|
+
</xsl:template>
|
|
991
|
+
|
|
992
|
+
<!-- ############ -->
|
|
993
|
+
<!-- Basic Blocks -->
|
|
994
|
+
<!-- ############ -->
|
|
995
|
+
|
|
996
|
+
<!-- The basic titled blocks: a bold heading from the localized -->
|
|
997
|
+
<!-- type-name, the number, and any title, run in to the leading -->
|
|
998
|
+
<!-- paragraph of the contents. -->
|
|
999
|
+
|
|
1000
|
+
<!-- A run-in heading is a bold inline, built by one of a few modes -->
|
|
1001
|
+
<!-- that vary in the number they show. The font style is reset, -->
|
|
1002
|
+
<!-- since the heading may land inside an italic THEOREM-LIKE -->
|
|
1003
|
+
<!-- statement. Each ends with a period and an optional title. -->
|
|
1004
|
+
|
|
1005
|
+
<!-- "heading-full": type-name, full number, and (for a THEOREM or -->
|
|
1006
|
+
<!-- AXIOM) the attributing creator. Basic blocks and inline -->
|
|
1007
|
+
<!-- exercises and projects. -->
|
|
1008
|
+
<xsl:template match="*" mode="heading-full">
|
|
1009
|
+
<fo:inline font-weight="bold" font-style="normal">
|
|
1010
|
+
<xsl:apply-templates select="." mode="type-name"/>
|
|
1011
|
+
<xsl:variable name="the-number">
|
|
1012
|
+
<xsl:apply-templates select="." mode="number"/>
|
|
1013
|
+
</xsl:variable>
|
|
1014
|
+
<xsl:if test="not($the-number = '')">
|
|
1015
|
+
<xsl:text> </xsl:text>
|
|
1016
|
+
<xsl:value-of select="$the-number"/>
|
|
1017
|
+
</xsl:if>
|
|
1018
|
+
<!-- attribution of a theorem or axiom, as in the HTML conversion -->
|
|
1019
|
+
<xsl:if test="creator and (&THEOREM-FILTER; or &AXIOM-FILTER;)">
|
|
1020
|
+
<xsl:text> (</xsl:text>
|
|
1021
|
+
<xsl:apply-templates select="." mode="creator-full"/>
|
|
1022
|
+
<xsl:text>)</xsl:text>
|
|
1023
|
+
</xsl:if>
|
|
1024
|
+
<xsl:text>.</xsl:text>
|
|
1025
|
+
<xsl:if test="title">
|
|
1026
|
+
<xsl:text> </xsl:text>
|
|
1027
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
1028
|
+
</xsl:if>
|
|
1029
|
+
</fo:inline>
|
|
1030
|
+
</xsl:template>
|
|
1031
|
+
|
|
1032
|
+
<!-- "heading-serial": just the compact serial number, no type-name. -->
|
|
1033
|
+
<!-- A divisional exercise (in "exercises", a "worksheet", or -->
|
|
1034
|
+
<!-- "reading-questions"). -->
|
|
1035
|
+
<xsl:template match="*" mode="heading-serial">
|
|
1036
|
+
<fo:inline font-weight="bold" font-style="normal">
|
|
1037
|
+
<xsl:apply-templates select="." mode="serial-number"/>
|
|
1038
|
+
<xsl:text>.</xsl:text>
|
|
1039
|
+
<xsl:if test="title">
|
|
1040
|
+
<xsl:text> </xsl:text>
|
|
1041
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
1042
|
+
</xsl:if>
|
|
1043
|
+
</fo:inline>
|
|
1044
|
+
</xsl:template>
|
|
1045
|
+
|
|
1046
|
+
<!-- "heading-list-number": a parenthesized list number, no type-name. -->
|
|
1047
|
+
<!-- A "task". -->
|
|
1048
|
+
<xsl:template match="*" mode="heading-list-number">
|
|
1049
|
+
<fo:inline font-weight="bold" font-style="normal">
|
|
1050
|
+
<xsl:text>(</xsl:text>
|
|
1051
|
+
<xsl:apply-templates select="." mode="list-number"/>
|
|
1052
|
+
<xsl:text>)</xsl:text>
|
|
1053
|
+
<xsl:if test="title">
|
|
1054
|
+
<xsl:text> </xsl:text>
|
|
1055
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
1056
|
+
</xsl:if>
|
|
1057
|
+
</fo:inline>
|
|
1058
|
+
</xsl:template>
|
|
1059
|
+
|
|
1060
|
+
<!-- An exercise or project run-in heading. The assembly stamps -->
|
|
1061
|
+
<!-- "@exercise-customization" with the exercise's category; the -->
|
|
1062
|
+
<!-- divisional kinds (divisional, worksheet, reading) show a bare -->
|
|
1063
|
+
<!-- serial number, while an inline exercise or a project carries -->
|
|
1064
|
+
<!-- the full type-name and number. -->
|
|
1065
|
+
<xsl:template match="*" mode="exercise-heading">
|
|
1066
|
+
<xsl:choose>
|
|
1067
|
+
<xsl:when test="@exercise-customization = 'inline' or @exercise-customization = 'project'">
|
|
1068
|
+
<xsl:apply-templates select="." mode="heading-full"/>
|
|
1069
|
+
</xsl:when>
|
|
1070
|
+
<xsl:otherwise>
|
|
1071
|
+
<xsl:apply-templates select="." mode="heading-serial"/>
|
|
1072
|
+
</xsl:otherwise>
|
|
1073
|
+
</xsl:choose>
|
|
1074
|
+
</xsl:template>
|
|
1075
|
+
|
|
1076
|
+
<!-- XSL-FO has no run-in display, so a heading is passed as the -->
|
|
1077
|
+
<!-- "run-in-heading" parameter to the leading paragraph, which -->
|
|
1078
|
+
<!-- prepends it ("statement" forwards the parameter through). -->
|
|
1079
|
+
<!-- When the content does not lead with a paragraph, the heading -->
|
|
1080
|
+
<!-- falls back to a standalone block. The context node is the -->
|
|
1081
|
+
<!-- block whose children are the content; "title" is metadata, -->
|
|
1082
|
+
<!-- consumed by the heading, and so not content. -->
|
|
1083
|
+
<xsl:template name="heading-then-content">
|
|
1084
|
+
<xsl:param name="heading"/>
|
|
1085
|
+
<!-- "idx" and "notation" are invisible markers, not content; -->
|
|
1086
|
+
<!-- render them for their side effects, but do not let them take -->
|
|
1087
|
+
<!-- the heading or block its run-in into a leading paragraph. -->
|
|
1088
|
+
<xsl:apply-templates select="idx | notation"/>
|
|
1089
|
+
<xsl:variable name="content" select="*[not(self::title) and not(self::idx) and not(self::notation)]"/>
|
|
1090
|
+
<xsl:choose>
|
|
1091
|
+
<xsl:when test="$content[1][self::p] or $content[1][self::statement and *[1][self::p]]">
|
|
1092
|
+
<xsl:apply-templates select="$content[1]">
|
|
1093
|
+
<xsl:with-param name="run-in-heading" select="$heading"/>
|
|
1094
|
+
</xsl:apply-templates>
|
|
1095
|
+
<xsl:apply-templates select="$content[position() > 1]"/>
|
|
1096
|
+
</xsl:when>
|
|
1097
|
+
<xsl:otherwise>
|
|
1098
|
+
<fo:block keep-with-next.within-page="always">
|
|
1099
|
+
<xsl:copy-of select="$heading"/>
|
|
1100
|
+
</fo:block>
|
|
1101
|
+
<xsl:apply-templates select="$content"/>
|
|
1102
|
+
</xsl:otherwise>
|
|
1103
|
+
</xsl:choose>
|
|
1104
|
+
</xsl:template>
|
|
1105
|
+
|
|
1106
|
+
<!-- The block families are identical in structure; the contents -->
|
|
1107
|
+
<!-- process in document order, so a "statement" leads and -->
|
|
1108
|
+
<!-- PROOF-LIKE or SOLUTION-LIKE follow. (Only a THEOREM-LIKE -->
|
|
1109
|
+
<!-- statement is italic, so a "definition" stays upright.) -->
|
|
1110
|
+
<!-- An "exercise" matching here is the *inline* flavor; a -->
|
|
1111
|
+
<!-- divisional one matches a more specific pattern in the -->
|
|
1112
|
+
<!-- "Exercises" section. PROJECT-LIKE blocks may also be -->
|
|
1113
|
+
<!-- structured by "task", arriving among the contents. -->
|
|
1114
|
+
<!-- DEFINITION-LIKE and EXAMPLE-LIKE are exceptions, closing -->
|
|
1115
|
+
<!-- with an end-mark, and so match a more specific pattern. -->
|
|
1116
|
+
<xsl:template match="&REMARK-LIKE;|&THEOREM-LIKE;|&AXIOM-LIKE;|&OPENPROBLEM-LIKE;|&COMPUTATION-LIKE;|&ASIDE-LIKE;|objectives|outcomes">
|
|
1117
|
+
<xsl:apply-templates select="." mode="forced-pagebreak"/>
|
|
1118
|
+
<fo:block space-before="1em" space-after="1em">
|
|
1119
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
1120
|
+
<xsl:variable name="heading">
|
|
1121
|
+
<xsl:apply-templates select="." mode="heading-full"/>
|
|
1122
|
+
<xsl:text> </xsl:text>
|
|
1123
|
+
</xsl:variable>
|
|
1124
|
+
<xsl:call-template name="heading-then-content">
|
|
1125
|
+
<xsl:with-param name="heading" select="$heading"/>
|
|
1126
|
+
</xsl:call-template>
|
|
1127
|
+
</fo:block>
|
|
1128
|
+
</xsl:template>
|
|
1129
|
+
|
|
1130
|
+
<!-- DEFINITION-LIKE and EXAMPLE-LIKE close with an end-mark, as -->
|
|
1131
|
+
<!-- in the LaTeX conversion: a filled diamond for a definition, -->
|
|
1132
|
+
<!-- a filled triangle for an example (the family of the -->
|
|
1133
|
+
<!-- PROOF-LIKE square). Otherwise these are ordinary run-in -->
|
|
1134
|
+
<!-- titled blocks; "block-with-end-mark" supplies the heading -->
|
|
1135
|
+
<!-- run-in, the contents, and the riding-or-own-line mark. -->
|
|
1136
|
+
<xsl:template match="&DEFINITION-LIKE;|&EXAMPLE-LIKE;">
|
|
1137
|
+
<xsl:apply-templates select="." mode="forced-pagebreak"/>
|
|
1138
|
+
<fo:block space-before="1em" space-after="1em">
|
|
1139
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
1140
|
+
<xsl:variable name="heading">
|
|
1141
|
+
<xsl:apply-templates select="." mode="heading-full"/>
|
|
1142
|
+
<xsl:text> </xsl:text>
|
|
1143
|
+
</xsl:variable>
|
|
1144
|
+
<xsl:call-template name="block-with-end-mark">
|
|
1145
|
+
<xsl:with-param name="heading" select="$heading"/>
|
|
1146
|
+
<xsl:with-param name="mark">
|
|
1147
|
+
<xsl:choose>
|
|
1148
|
+
<!-- BLACK DIAMOND -->
|
|
1149
|
+
<xsl:when test="&DEFINITION-FILTER;">
|
|
1150
|
+
<xsl:text>◆</xsl:text>
|
|
1151
|
+
</xsl:when>
|
|
1152
|
+
<!-- BLACK UP-POINTING TRIANGLE -->
|
|
1153
|
+
<xsl:otherwise>
|
|
1154
|
+
<xsl:text>▲</xsl:text>
|
|
1155
|
+
</xsl:otherwise>
|
|
1156
|
+
</xsl:choose>
|
|
1157
|
+
</xsl:with-param>
|
|
1158
|
+
</xsl:call-template>
|
|
1159
|
+
</fo:block>
|
|
1160
|
+
</xsl:template>
|
|
1161
|
+
|
|
1162
|
+
<!-- An "assemblage" is an informal, decorative box. Unlike the -->
|
|
1163
|
+
<!-- run-in headings of the theorem-like families, its optional -->
|
|
1164
|
+
<!-- title is a centered heading above the content, as in the HTML -->
|
|
1165
|
+
<!-- and LaTeX conversions; an untitled assemblage has no heading. -->
|
|
1166
|
+
<xsl:template match="assemblage">
|
|
1167
|
+
<xsl:apply-templates select="." mode="forced-pagebreak"/>
|
|
1168
|
+
<!-- A prominent enclosing box, matching the LaTeX conversion's -->
|
|
1169
|
+
<!-- tcolorbox: a thin black frame (0.5mm, the tcolorbox default) -->
|
|
1170
|
+
<!-- on the white page, with padding between frame and content. -->
|
|
1171
|
+
<!-- Start- and end-indents hold the frame within the text -->
|
|
1172
|
+
<!-- margins, since FO draws border and padding outward. -->
|
|
1173
|
+
<!-- XSL-FO/FOP has no rounded corners, so the box is square; a -->
|
|
1174
|
+
<!-- finite keep prefers the box whole on a page but yields if it -->
|
|
1175
|
+
<!-- is too tall, rather than clip it. -->
|
|
1176
|
+
<fo:block space-before="1em" space-after="1em" border="0.5mm solid black" padding="2mm" start-indent="2.5mm" end-indent="2.5mm" keep-together.within-page="5">
|
|
1177
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
1178
|
+
<xsl:if test="title">
|
|
1179
|
+
<fo:block font-weight="bold" text-align="center" space-after="0.5em" keep-with-next.within-page="always">
|
|
1180
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
1181
|
+
</fo:block>
|
|
1182
|
+
</xsl:if>
|
|
1183
|
+
<xsl:apply-templates select="*[not(self::title)]"/>
|
|
1184
|
+
</fo:block>
|
|
1185
|
+
</xsl:template>
|
|
1186
|
+
|
|
1187
|
+
<!-- A general-purpose container, otherwise transparent, though -->
|
|
1188
|
+
<!-- the statement of a THEOREM-LIKE is italic, by mathematical -->
|
|
1189
|
+
<!-- tradition. -->
|
|
1190
|
+
<!-- A "statement" is transparent, but threads a run-in heading to -->
|
|
1191
|
+
<!-- its first child and an end-mark to its last, so a block whose -->
|
|
1192
|
+
<!-- content is wrapped in a "statement" (a "definition", say) still -->
|
|
1193
|
+
<!-- runs its heading in and rides its closing mark. -->
|
|
1194
|
+
<xsl:template match="statement">
|
|
1195
|
+
<xsl:param name="run-in-heading"/>
|
|
1196
|
+
<xsl:param name="trailing-tombstone"/>
|
|
1197
|
+
<xsl:variable name="body">
|
|
1198
|
+
<xsl:choose>
|
|
1199
|
+
<xsl:when test="count(*) = 1">
|
|
1200
|
+
<xsl:apply-templates select="*[1]">
|
|
1201
|
+
<xsl:with-param name="run-in-heading" select="$run-in-heading"/>
|
|
1202
|
+
<xsl:with-param name="trailing-tombstone" select="$trailing-tombstone"/>
|
|
1203
|
+
</xsl:apply-templates>
|
|
1204
|
+
</xsl:when>
|
|
1205
|
+
<xsl:otherwise>
|
|
1206
|
+
<xsl:apply-templates select="*[1]">
|
|
1207
|
+
<xsl:with-param name="run-in-heading" select="$run-in-heading"/>
|
|
1208
|
+
</xsl:apply-templates>
|
|
1209
|
+
<xsl:apply-templates select="*[(position() > 1) and (position() < last())]"/>
|
|
1210
|
+
<xsl:apply-templates select="*[last()]">
|
|
1211
|
+
<xsl:with-param name="trailing-tombstone" select="$trailing-tombstone"/>
|
|
1212
|
+
</xsl:apply-templates>
|
|
1213
|
+
</xsl:otherwise>
|
|
1214
|
+
</xsl:choose>
|
|
1215
|
+
</xsl:variable>
|
|
1216
|
+
<xsl:choose>
|
|
1217
|
+
<xsl:when test="parent::*[&THEOREM-FILTER;]">
|
|
1218
|
+
<fo:block font-style="italic">
|
|
1219
|
+
<xsl:copy-of select="$body"/>
|
|
1220
|
+
</fo:block>
|
|
1221
|
+
</xsl:when>
|
|
1222
|
+
<xsl:otherwise>
|
|
1223
|
+
<xsl:copy-of select="$body"/>
|
|
1224
|
+
</xsl:otherwise>
|
|
1225
|
+
</xsl:choose>
|
|
1226
|
+
</xsl:template>
|
|
1227
|
+
|
|
1228
|
+
<!-- A titled block whose family closes with an end-mark: the -->
|
|
1229
|
+
<!-- PROOF-LIKE tombstone, or the DEFINITION-LIKE / EXAMPLE-LIKE -->
|
|
1230
|
+
<!-- mark. When the block ends in a paragraph the mark rides its -->
|
|
1231
|
+
<!-- final line, an elastic leader pushing it to the right margin; -->
|
|
1232
|
+
<!-- the closing paragraph may be wrapped in a "statement" (the -->
|
|
1233
|
+
<!-- usual shape of a "definition"), which threads the mark on -->
|
|
1234
|
+
<!-- through. Otherwise (a closing display, list, "case", or -->
|
|
1235
|
+
<!-- "solution") the mark takes a line of its own, kept on the page -->
|
|
1236
|
+
<!-- where the content ended so it never leads an orphaned page; -->
|
|
1237
|
+
<!-- chasing the mark down into those would be heroics. The -->
|
|
1238
|
+
<!-- heading runs into a leading paragraph, directly or within a -->
|
|
1239
|
+
<!-- "statement", as in "heading-then-content". The mark glyph -->
|
|
1240
|
+
<!-- (passed as a code point) comes from the symbol font. -->
|
|
1241
|
+
<xsl:template name="block-with-end-mark">
|
|
1242
|
+
<xsl:param name="heading"/>
|
|
1243
|
+
<xsl:param name="mark"/>
|
|
1244
|
+
<xsl:variable name="end-mark">
|
|
1245
|
+
<fo:leader leader-pattern="space"/>
|
|
1246
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
1247
|
+
<xsl:value-of select="$mark"/>
|
|
1248
|
+
</fo:inline>
|
|
1249
|
+
</xsl:variable>
|
|
1250
|
+
<!-- "idx" and "notation" are invisible markers (an index entry, -->
|
|
1251
|
+
<!-- the notation list), not content: render them for those side -->
|
|
1252
|
+
<!-- effects, but keep them from taking the heading or the mark, -->
|
|
1253
|
+
<!-- or blocking the heading's run-in (a "definition" often leads -->
|
|
1254
|
+
<!-- with them). -->
|
|
1255
|
+
<xsl:apply-templates select="idx | notation"/>
|
|
1256
|
+
<xsl:variable name="content" select="*[not(self::title) and not(self::idx) and not(self::notation)]"/>
|
|
1257
|
+
<xsl:variable name="last" select="$content[last()]"/>
|
|
1258
|
+
<!-- The mark rides a closing paragraph only when that paragraph -->
|
|
1259
|
+
<!-- holds running text alone. A paragraph that carries a display -->
|
|
1260
|
+
<!-- ("...written as <md/>") would otherwise have its line -->
|
|
1261
|
+
<!-- justified (to push the mark to the margin), spreading the text -->
|
|
1262
|
+
<!-- around the display; such a block takes the mark on its own -->
|
|
1263
|
+
<!-- line instead. -->
|
|
1264
|
+
<xsl:variable name="b-mark-rides" select="boolean(($last[self::p] and not($last/md)) or ($last[self::statement] and $last/*[last()][self::p] and not($last/*[last()]/md)))"/>
|
|
1265
|
+
<!-- the heading runs in to a leading paragraph, plain or in a "statement" -->
|
|
1266
|
+
<xsl:choose>
|
|
1267
|
+
<xsl:when test="$content[1][self::p] or ($content[1][self::statement] and $content[1]/*[1][self::p])">
|
|
1268
|
+
<xsl:apply-templates select="$content[1]">
|
|
1269
|
+
<xsl:with-param name="run-in-heading" select="$heading"/>
|
|
1270
|
+
<xsl:with-param name="trailing-tombstone">
|
|
1271
|
+
<xsl:if test="(count($content) = 1) and $b-mark-rides">
|
|
1272
|
+
<xsl:copy-of select="$end-mark"/>
|
|
1273
|
+
</xsl:if>
|
|
1274
|
+
</xsl:with-param>
|
|
1275
|
+
</xsl:apply-templates>
|
|
1276
|
+
</xsl:when>
|
|
1277
|
+
<xsl:otherwise>
|
|
1278
|
+
<fo:block keep-with-next.within-page="always">
|
|
1279
|
+
<xsl:copy-of select="$heading"/>
|
|
1280
|
+
</fo:block>
|
|
1281
|
+
<xsl:apply-templates select="$content[1]"/>
|
|
1282
|
+
</xsl:otherwise>
|
|
1283
|
+
</xsl:choose>
|
|
1284
|
+
<xsl:apply-templates select="$content[(position() > 1) and (position() < last())]"/>
|
|
1285
|
+
<xsl:if test="count($content) > 1">
|
|
1286
|
+
<xsl:apply-templates select="$content[last()]">
|
|
1287
|
+
<xsl:with-param name="trailing-tombstone">
|
|
1288
|
+
<xsl:if test="$b-mark-rides">
|
|
1289
|
+
<xsl:copy-of select="$end-mark"/>
|
|
1290
|
+
</xsl:if>
|
|
1291
|
+
</xsl:with-param>
|
|
1292
|
+
</xsl:apply-templates>
|
|
1293
|
+
</xsl:if>
|
|
1294
|
+
<xsl:if test="not($b-mark-rides)">
|
|
1295
|
+
<fo:block text-align-last="justify" keep-with-previous.within-page="always">
|
|
1296
|
+
<xsl:copy-of select="$end-mark"/>
|
|
1297
|
+
</fo:block>
|
|
1298
|
+
</xsl:if>
|
|
1299
|
+
</xsl:template>
|
|
1300
|
+
|
|
1301
|
+
<!-- An italic run-in heading, the contents, and a filled square -->
|
|
1302
|
+
<!-- (QED, Halmos) to finish, matching the LaTeX conversion. -->
|
|
1303
|
+
<xsl:template match="&PROOF-LIKE;">
|
|
1304
|
+
<fo:block space-before="1em" space-after="1em">
|
|
1305
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
1306
|
+
<xsl:variable name="heading">
|
|
1307
|
+
<fo:inline font-style="italic">
|
|
1308
|
+
<xsl:apply-templates select="." mode="type-name"/>
|
|
1309
|
+
<xsl:text>.</xsl:text>
|
|
1310
|
+
</fo:inline>
|
|
1311
|
+
<xsl:text> </xsl:text>
|
|
1312
|
+
</xsl:variable>
|
|
1313
|
+
<xsl:call-template name="block-with-end-mark">
|
|
1314
|
+
<xsl:with-param name="heading" select="$heading"/>
|
|
1315
|
+
<!-- BLACK SQUARE -->
|
|
1316
|
+
<xsl:with-param name="mark" select="'■'"/>
|
|
1317
|
+
</xsl:call-template>
|
|
1318
|
+
</fo:block>
|
|
1319
|
+
</xsl:template>
|
|
1320
|
+
|
|
1321
|
+
<!-- A "case" of a proof: an italic run-in heading built from the -->
|
|
1322
|
+
<!-- direction arrow and/or the title (an untitled, undirected -->
|
|
1323
|
+
<!-- case earns the default title, "Case."), as in the HTML -->
|
|
1324
|
+
<!-- conversion. -->
|
|
1325
|
+
<xsl:template match="case">
|
|
1326
|
+
<fo:block space-before="0.75em" space-after="0.5em">
|
|
1327
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
1328
|
+
<xsl:variable name="heading">
|
|
1329
|
+
<fo:inline font-style="italic">
|
|
1330
|
+
<xsl:apply-templates select="." mode="case-direction"/>
|
|
1331
|
+
<xsl:if test="boolean(title) or not(@direction)">
|
|
1332
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
1333
|
+
</xsl:if>
|
|
1334
|
+
</fo:inline>
|
|
1335
|
+
<xsl:text> </xsl:text>
|
|
1336
|
+
</xsl:variable>
|
|
1337
|
+
<xsl:call-template name="heading-then-content">
|
|
1338
|
+
<xsl:with-param name="heading" select="$heading"/>
|
|
1339
|
+
</xsl:call-template>
|
|
1340
|
+
</fo:block>
|
|
1341
|
+
</xsl:template>
|
|
1342
|
+
|
|
1343
|
+
<!-- The implication arrows of a "case" direction, and the spacing -->
|
|
1344
|
+
<!-- inside a "cycle" decoration, expected by pretext-common.xsl. -->
|
|
1345
|
+
<!-- The double arrows are taken from the symbol font: the main body -->
|
|
1346
|
+
<!-- font (e.g. Latin Modern Roman) need not carry them. -->
|
|
1347
|
+
<xsl:template name="double-right-arrow-symbol">
|
|
1348
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
1349
|
+
<!-- RIGHTWARDS DOUBLE ARROW -->
|
|
1350
|
+
<xsl:text>⇒</xsl:text>
|
|
1351
|
+
</fo:inline>
|
|
1352
|
+
</xsl:template>
|
|
1353
|
+
<xsl:template name="double-left-arrow-symbol">
|
|
1354
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
1355
|
+
<!-- LEFTWARDS DOUBLE ARROW -->
|
|
1356
|
+
<xsl:text>⇐</xsl:text>
|
|
1357
|
+
</fo:inline>
|
|
1358
|
+
</xsl:template>
|
|
1359
|
+
<xsl:template name="case-cycle-delimiter-space">
|
|
1360
|
+
<!-- THIN SPACE -->
|
|
1361
|
+
<xsl:text> </xsl:text>
|
|
1362
|
+
</xsl:template>
|
|
1363
|
+
|
|
1364
|
+
<!-- A hint, answer, or solution appends an exercise or example; a -->
|
|
1365
|
+
<!-- context, discussion, opinion, status, or suggestion appends an -->
|
|
1366
|
+
<!-- open problem. All render alike: a bold run-in type-name, a -->
|
|
1367
|
+
<!-- serial number, an optional parenthesized title, and a period, -->
|
|
1368
|
+
<!-- rendered run-in via heading-then-content as for any block. -->
|
|
1369
|
+
<xsl:template match="&SOLUTION-LIKE;|&DISCUSSION-LIKE;">
|
|
1370
|
+
<fo:block space-before="1em">
|
|
1371
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
1372
|
+
<xsl:variable name="heading">
|
|
1373
|
+
<xsl:apply-templates select="." mode="appendage-heading"/>
|
|
1374
|
+
<xsl:text> </xsl:text>
|
|
1375
|
+
</xsl:variable>
|
|
1376
|
+
<xsl:call-template name="heading-then-content">
|
|
1377
|
+
<xsl:with-param name="heading" select="$heading"/>
|
|
1378
|
+
</xsl:call-template>
|
|
1379
|
+
</fo:block>
|
|
1380
|
+
</xsl:template>
|
|
1381
|
+
|
|
1382
|
+
<!-- The run-in heading of an appendage: a bold type-name and a -->
|
|
1383
|
+
<!-- serial number, with an optional parenthesized title and a -->
|
|
1384
|
+
<!-- period. A hint, answer, or solution shows its number only -->
|
|
1385
|
+
<!-- with same-kind siblings ("Hint" alone, else "Hint 1", ...); -->
|
|
1386
|
+
<!-- open-problem appendages are always numbered, as in LaTeX. -->
|
|
1387
|
+
<xsl:template match="*" mode="appendage-heading">
|
|
1388
|
+
<xsl:variable name="the-number">
|
|
1389
|
+
<xsl:choose>
|
|
1390
|
+
<xsl:when test="self::hint or self::answer or self::solution">
|
|
1391
|
+
<xsl:apply-templates select="." mode="non-singleton-number"/>
|
|
1392
|
+
</xsl:when>
|
|
1393
|
+
<xsl:otherwise>
|
|
1394
|
+
<xsl:apply-templates select="." mode="serial-number"/>
|
|
1395
|
+
</xsl:otherwise>
|
|
1396
|
+
</xsl:choose>
|
|
1397
|
+
</xsl:variable>
|
|
1398
|
+
<fo:inline font-weight="bold" font-style="normal">
|
|
1399
|
+
<xsl:apply-templates select="." mode="type-name"/>
|
|
1400
|
+
<xsl:if test="not($the-number = '')">
|
|
1401
|
+
<xsl:text> </xsl:text>
|
|
1402
|
+
<xsl:value-of select="$the-number"/>
|
|
1403
|
+
</xsl:if>
|
|
1404
|
+
</fo:inline>
|
|
1405
|
+
<xsl:if test="title">
|
|
1406
|
+
<xsl:text> (</xsl:text>
|
|
1407
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
1408
|
+
<xsl:text>)</xsl:text>
|
|
1409
|
+
</xsl:if>
|
|
1410
|
+
<xsl:text>.</xsl:text>
|
|
1411
|
+
</xsl:template>
|
|
1412
|
+
|
|
1413
|
+
<!-- ######### -->
|
|
1414
|
+
<!-- Exercises -->
|
|
1415
|
+
<!-- ######### -->
|
|
1416
|
+
|
|
1417
|
+
<!-- All the EXERCISE-LIKE and PROJECT-LIKE render through the -->
|
|
1418
|
+
<!-- "exercise-components" machinery below, honoring the publisher -->
|
|
1419
|
+
<!-- file's visibility switches for the matching collection (e.g. -->
|
|
1420
|
+
<!-- divisional hints in the main text). Headings: an *inline* -->
|
|
1421
|
+
<!-- exercise ("Checkpoint") or project carries full type-name and -->
|
|
1422
|
+
<!-- number; a *divisional* one (in an "exercises" division, a -->
|
|
1423
|
+
<!-- "worksheet", or "reading-questions") a compact serial number. -->
|
|
1424
|
+
<xsl:template match="exercise|&PROJECT-LIKE;">
|
|
1425
|
+
<xsl:apply-templates select="." mode="forced-pagebreak"/>
|
|
1426
|
+
<fo:block space-before="1em" space-after="1em">
|
|
1427
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
1428
|
+
<!-- index anchors; the components machinery below will not visit them -->
|
|
1429
|
+
<xsl:apply-templates select="idx"/>
|
|
1430
|
+
<xsl:variable name="heading">
|
|
1431
|
+
<xsl:apply-templates select="." mode="exercise-heading"/>
|
|
1432
|
+
<xsl:text> </xsl:text>
|
|
1433
|
+
</xsl:variable>
|
|
1434
|
+
<xsl:apply-templates select="." mode="exercise-components">
|
|
1435
|
+
<xsl:with-param name="b-original" select="true()"/>
|
|
1436
|
+
<xsl:with-param name="b-has-statement" select="true()"/>
|
|
1437
|
+
<xsl:with-param name="b-has-hint">
|
|
1438
|
+
<xsl:apply-templates select="." mode="b-main-text-component">
|
|
1439
|
+
<xsl:with-param name="component" select="'hint'"/>
|
|
1440
|
+
</xsl:apply-templates>
|
|
1441
|
+
</xsl:with-param>
|
|
1442
|
+
<xsl:with-param name="b-has-answer">
|
|
1443
|
+
<xsl:apply-templates select="." mode="b-main-text-component">
|
|
1444
|
+
<xsl:with-param name="component" select="'answer'"/>
|
|
1445
|
+
</xsl:apply-templates>
|
|
1446
|
+
</xsl:with-param>
|
|
1447
|
+
<xsl:with-param name="b-has-solution">
|
|
1448
|
+
<xsl:apply-templates select="." mode="b-main-text-component">
|
|
1449
|
+
<xsl:with-param name="component" select="'solution'"/>
|
|
1450
|
+
</xsl:apply-templates>
|
|
1451
|
+
</xsl:with-param>
|
|
1452
|
+
<xsl:with-param name="run-in-heading" select="$heading"/>
|
|
1453
|
+
</xsl:apply-templates>
|
|
1454
|
+
<!-- writing space below, in a printout, when requested -->
|
|
1455
|
+
<xsl:apply-templates select="." mode="workspace"/>
|
|
1456
|
+
</fo:block>
|
|
1457
|
+
</xsl:template>
|
|
1458
|
+
|
|
1459
|
+
<!-- A "task" reached in document order (e.g. structuring an -->
|
|
1460
|
+
<!-- EXAMPLE-LIKE): its label and all its components. -->
|
|
1461
|
+
<xsl:template match="task">
|
|
1462
|
+
<fo:block space-before="0.75em" space-after="0.75em">
|
|
1463
|
+
<!-- a sub-task indents one step deeper than its parent -->
|
|
1464
|
+
<xsl:attribute name="start-indent">
|
|
1465
|
+
<xsl:value-of select="count(ancestor-or-self::task) * $task-indentation"/>
|
|
1466
|
+
<xsl:text>em</xsl:text>
|
|
1467
|
+
</xsl:attribute>
|
|
1468
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
1469
|
+
<xsl:apply-templates select="idx"/>
|
|
1470
|
+
<xsl:variable name="heading">
|
|
1471
|
+
<xsl:apply-templates select="." mode="heading-list-number"/>
|
|
1472
|
+
<xsl:text> </xsl:text>
|
|
1473
|
+
</xsl:variable>
|
|
1474
|
+
<xsl:apply-templates select="." mode="exercise-components">
|
|
1475
|
+
<xsl:with-param name="run-in-heading" select="$heading"/>
|
|
1476
|
+
<xsl:with-param name="b-original" select="true()"/>
|
|
1477
|
+
<xsl:with-param name="b-has-statement" select="true()"/>
|
|
1478
|
+
<xsl:with-param name="b-has-hint" select="true()"/>
|
|
1479
|
+
<xsl:with-param name="b-has-answer" select="true()"/>
|
|
1480
|
+
<xsl:with-param name="b-has-solution" select="true()"/>
|
|
1481
|
+
</xsl:apply-templates>
|
|
1482
|
+
<!-- writing space below a terminal task, in a printout -->
|
|
1483
|
+
<xsl:apply-templates select="." mode="workspace"/>
|
|
1484
|
+
</fo:block>
|
|
1485
|
+
</xsl:template>
|
|
1486
|
+
|
|
1487
|
+
<!-- The publisher's main-text visibility switch for one component -->
|
|
1488
|
+
<!-- of this exercise, by the collection it sits in. (XSLT 1.0 -->
|
|
1489
|
+
<!-- carries the boolean home as the string "true" or "false".) -->
|
|
1490
|
+
<xsl:template match="*" mode="b-main-text-component">
|
|
1491
|
+
<xsl:param name="component"/>
|
|
1492
|
+
<xsl:choose>
|
|
1493
|
+
<xsl:when test="self::exercise and ancestor::exercises">
|
|
1494
|
+
<xsl:choose>
|
|
1495
|
+
<xsl:when test="$component = 'hint'">
|
|
1496
|
+
<xsl:value-of select="$b-has-divisional-hint"/>
|
|
1497
|
+
</xsl:when>
|
|
1498
|
+
<xsl:when test="$component = 'answer'">
|
|
1499
|
+
<xsl:value-of select="$b-has-divisional-answer"/>
|
|
1500
|
+
</xsl:when>
|
|
1501
|
+
<xsl:otherwise>
|
|
1502
|
+
<xsl:value-of select="$b-has-divisional-solution"/>
|
|
1503
|
+
</xsl:otherwise>
|
|
1504
|
+
</xsl:choose>
|
|
1505
|
+
</xsl:when>
|
|
1506
|
+
<xsl:when test="self::exercise and ancestor::worksheet">
|
|
1507
|
+
<xsl:choose>
|
|
1508
|
+
<xsl:when test="$component = 'hint'">
|
|
1509
|
+
<xsl:value-of select="$b-has-worksheet-hint"/>
|
|
1510
|
+
</xsl:when>
|
|
1511
|
+
<xsl:when test="$component = 'answer'">
|
|
1512
|
+
<xsl:value-of select="$b-has-worksheet-answer"/>
|
|
1513
|
+
</xsl:when>
|
|
1514
|
+
<xsl:otherwise>
|
|
1515
|
+
<xsl:value-of select="$b-has-worksheet-solution"/>
|
|
1516
|
+
</xsl:otherwise>
|
|
1517
|
+
</xsl:choose>
|
|
1518
|
+
</xsl:when>
|
|
1519
|
+
<xsl:when test="self::exercise and ancestor::reading-questions">
|
|
1520
|
+
<xsl:choose>
|
|
1521
|
+
<xsl:when test="$component = 'hint'">
|
|
1522
|
+
<xsl:value-of select="$b-has-reading-hint"/>
|
|
1523
|
+
</xsl:when>
|
|
1524
|
+
<xsl:when test="$component = 'answer'">
|
|
1525
|
+
<xsl:value-of select="$b-has-reading-answer"/>
|
|
1526
|
+
</xsl:when>
|
|
1527
|
+
<xsl:otherwise>
|
|
1528
|
+
<xsl:value-of select="$b-has-reading-solution"/>
|
|
1529
|
+
</xsl:otherwise>
|
|
1530
|
+
</xsl:choose>
|
|
1531
|
+
</xsl:when>
|
|
1532
|
+
<xsl:when test="self::exercise">
|
|
1533
|
+
<xsl:choose>
|
|
1534
|
+
<xsl:when test="$component = 'hint'">
|
|
1535
|
+
<xsl:value-of select="$b-has-inline-hint"/>
|
|
1536
|
+
</xsl:when>
|
|
1537
|
+
<xsl:when test="$component = 'answer'">
|
|
1538
|
+
<xsl:value-of select="$b-has-inline-answer"/>
|
|
1539
|
+
</xsl:when>
|
|
1540
|
+
<xsl:otherwise>
|
|
1541
|
+
<xsl:value-of select="$b-has-inline-solution"/>
|
|
1542
|
+
</xsl:otherwise>
|
|
1543
|
+
</xsl:choose>
|
|
1544
|
+
</xsl:when>
|
|
1545
|
+
<!-- PROJECT-LIKE -->
|
|
1546
|
+
<xsl:otherwise>
|
|
1547
|
+
<xsl:choose>
|
|
1548
|
+
<xsl:when test="$component = 'hint'">
|
|
1549
|
+
<xsl:value-of select="$b-has-project-hint"/>
|
|
1550
|
+
</xsl:when>
|
|
1551
|
+
<xsl:when test="$component = 'answer'">
|
|
1552
|
+
<xsl:value-of select="$b-has-project-answer"/>
|
|
1553
|
+
</xsl:when>
|
|
1554
|
+
<xsl:otherwise>
|
|
1555
|
+
<xsl:value-of select="$b-has-project-solution"/>
|
|
1556
|
+
</xsl:otherwise>
|
|
1557
|
+
</xsl:choose>
|
|
1558
|
+
</xsl:otherwise>
|
|
1559
|
+
</xsl:choose>
|
|
1560
|
+
</xsl:template>
|
|
1561
|
+
|
|
1562
|
+
<!-- A "prelude", "interlude", or "postlude" decorates a project -->
|
|
1563
|
+
<!-- or listing with surrounding prose; the contents just flow. -->
|
|
1564
|
+
<xsl:template match="prelude|interlude|postlude">
|
|
1565
|
+
<xsl:apply-templates select="*"/>
|
|
1566
|
+
</xsl:template>
|
|
1567
|
+
|
|
1568
|
+
<!-- A "subexercises" groups exercises under an interior heading. -->
|
|
1569
|
+
<xsl:template match="subexercises">
|
|
1570
|
+
<fo:block>
|
|
1571
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
1572
|
+
<xsl:if test="title">
|
|
1573
|
+
<fo:block font-weight="bold"
|
|
1574
|
+
space-before="1em"
|
|
1575
|
+
space-after="0.5em"
|
|
1576
|
+
keep-with-next.within-page="always">
|
|
1577
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
1578
|
+
</fo:block>
|
|
1579
|
+
</xsl:if>
|
|
1580
|
+
<xsl:apply-templates select="*[not(self::title)]"/>
|
|
1581
|
+
</fo:block>
|
|
1582
|
+
</xsl:template>
|
|
1583
|
+
|
|
1584
|
+
<!-- An "exercisegroup" supplies common context for consecutive -->
|
|
1585
|
+
<!-- exercises; numbering just continues through it. An author's -->
|
|
1586
|
+
<!-- @cols request (2 to 6, by the schema) arranges the exercises -->
|
|
1587
|
+
<!-- in that many equal columns, progressing across each row; a -->
|
|
1588
|
+
<!-- final short row pads with empty cells, since the rows of a -->
|
|
1589
|
+
<!-- tagged table must share a common width (ISO 14289-1). -->
|
|
1590
|
+
<xsl:template match="exercisegroup">
|
|
1591
|
+
<!-- the exercises shift right to show the scope of the group, by -->
|
|
1592
|
+
<!-- the shared fraction of the text measure (LaTeX's \egindent); -->
|
|
1593
|
+
<!-- the introduction and conclusion stay at the left margin -->
|
|
1594
|
+
<xsl:variable name="group-indent" select="format-number($exercisegroup-indentation * $text-width-points, '0.##')"/>
|
|
1595
|
+
<fo:block>
|
|
1596
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
1597
|
+
<xsl:apply-templates select="idx"/>
|
|
1598
|
+
<xsl:apply-templates select="introduction"/>
|
|
1599
|
+
<fo:block start-indent="{$group-indent}pt">
|
|
1600
|
+
<xsl:choose>
|
|
1601
|
+
<xsl:when test="@cols">
|
|
1602
|
+
<xsl:variable name="cols" select="@cols"/>
|
|
1603
|
+
<fo:table table-layout="fixed" width="100%">
|
|
1604
|
+
<xsl:call-template name="equal-table-columns">
|
|
1605
|
+
<xsl:with-param name="remaining" select="$cols"/>
|
|
1606
|
+
</xsl:call-template>
|
|
1607
|
+
<fo:table-body>
|
|
1608
|
+
<xsl:for-each select="exercise[(position() mod $cols) = 1]">
|
|
1609
|
+
<fo:table-row>
|
|
1610
|
+
<xsl:variable name="row-exercises" select=".|following-sibling::exercise[position() < $cols]"/>
|
|
1611
|
+
<xsl:for-each select="$row-exercises">
|
|
1612
|
+
<fo:table-cell padding-right="6pt">
|
|
1613
|
+
<xsl:apply-templates select="."/>
|
|
1614
|
+
</fo:table-cell>
|
|
1615
|
+
</xsl:for-each>
|
|
1616
|
+
<xsl:call-template name="empty-table-cells">
|
|
1617
|
+
<xsl:with-param name="remaining" select="$cols - count($row-exercises)"/>
|
|
1618
|
+
</xsl:call-template>
|
|
1619
|
+
</fo:table-row>
|
|
1620
|
+
</xsl:for-each>
|
|
1621
|
+
</fo:table-body>
|
|
1622
|
+
</fo:table>
|
|
1623
|
+
</xsl:when>
|
|
1624
|
+
<xsl:otherwise>
|
|
1625
|
+
<xsl:apply-templates select="exercise"/>
|
|
1626
|
+
</xsl:otherwise>
|
|
1627
|
+
</xsl:choose>
|
|
1628
|
+
</fo:block>
|
|
1629
|
+
<xsl:apply-templates select="conclusion"/>
|
|
1630
|
+
</fo:block>
|
|
1631
|
+
</xsl:template>
|
|
1632
|
+
|
|
1633
|
+
<!-- Workspace in a Printout -->
|
|
1634
|
+
<!-- ####################### -->
|
|
1635
|
+
|
|
1636
|
+
<!-- A worksheet or handout is a printout, and an author may request -->
|
|
1637
|
+
<!-- blank space below an exercise (or terminal task) where a reader -->
|
|
1638
|
+
<!-- works: "sanitize-workspace" (pretext-common.xsl) reduces the -->
|
|
1639
|
+
<!-- @workspace in effect to an absolute length, or to nothing. The -->
|
|
1640
|
+
<!-- space is elastic, in the manner of the LaTeX conversion's -->
|
|
1641
|
+
<!-- "vfill": the request is the natural size, a minimum in spirit; -->
|
|
1642
|
+
<!-- the space may surrender a quarter on a crowded page, and it can -->
|
|
1643
|
+
<!-- grow severalfold, so the workspace of a page's final exercise -->
|
|
1644
|
+
<!-- expands to fill the remainder of the printout's page. The -->
|
|
1645
|
+
<!-- "retain" sends a space interrupted by a page break wholly onto -->
|
|
1646
|
+
<!-- the next page, rather than quietly discarding it. -->
|
|
1647
|
+
<xsl:template match="*" mode="workspace">
|
|
1648
|
+
<xsl:variable name="vertical-space">
|
|
1649
|
+
<xsl:apply-templates select="." mode="sanitize-workspace"/>
|
|
1650
|
+
</xsl:variable>
|
|
1651
|
+
<xsl:if test="not($vertical-space = '')">
|
|
1652
|
+
<xsl:variable name="magnitude" select="substring($vertical-space, 1, string-length($vertical-space) - 2)"/>
|
|
1653
|
+
<xsl:variable name="unit" select="substring($vertical-space, string-length($vertical-space) - 1)"/>
|
|
1654
|
+
<fo:block space-before.minimum="{format-number(0.75 * $magnitude, '0.##')}{$unit}"
|
|
1655
|
+
space-before.optimum="{$vertical-space}"
|
|
1656
|
+
space-before.maximum="{format-number(4 * $magnitude, '0.##')}{$unit}"
|
|
1657
|
+
space-before.conditionality="retain">
|
|
1658
|
+
<!-- The publisher's draft mode makes the workspace visible -->
|
|
1659
|
+
<!-- with a faint hairline along its bottom edge, akin to -->
|
|
1660
|
+
<!-- the visible strut of the LaTeX conversion. -->
|
|
1661
|
+
<xsl:if test="$b-latex-draft-mode">
|
|
1662
|
+
<fo:leader leader-pattern="rule"
|
|
1663
|
+
leader-length.optimum="100%"
|
|
1664
|
+
rule-thickness="0.5pt"
|
|
1665
|
+
color="#999999"/>
|
|
1666
|
+
</xsl:if>
|
|
1667
|
+
</fo:block>
|
|
1668
|
+
</xsl:if>
|
|
1669
|
+
</xsl:template>
|
|
1670
|
+
|
|
1671
|
+
<!-- The publisher may decline printout formatting wholesale -->
|
|
1672
|
+
<!-- (pagination, workspace); then workspace requests evaporate, -->
|
|
1673
|
+
<!-- exactly as in the LaTeX conversion. -->
|
|
1674
|
+
<xsl:template match="*" mode="sanitize-workspace">
|
|
1675
|
+
<xsl:if test="$b-latex-worksheet-formatted">
|
|
1676
|
+
<xsl:apply-imports/>
|
|
1677
|
+
</xsl:if>
|
|
1678
|
+
</xsl:template>
|
|
1679
|
+
|
|
1680
|
+
<!-- Components of an Exercise -->
|
|
1681
|
+
<!-- ########################## -->
|
|
1682
|
+
|
|
1683
|
+
<!-- The components of EXERCISE-LIKE and PROJECT-LIKE: a statement -->
|
|
1684
|
+
<!-- and SOLUTION-LIKE appendages, each rendered only when the -->
|
|
1685
|
+
<!-- collection at hand wants it (the $b-has-* parameters: the -->
|
|
1686
|
+
<!-- publisher's main-text switches, or the configuration of a -->
|
|
1687
|
+
<!-- "solutions" division). The "run-in-heading" travels into a -->
|
|
1688
|
+
<!-- displayed statement, exactly as in "heading-then-content". -->
|
|
1689
|
+
|
|
1690
|
+
<!-- structured by "task": optional introduction and conclusion -->
|
|
1691
|
+
<!-- sandwich the tasks, each with its label and own components -->
|
|
1692
|
+
<!-- The walk over a sequence of "task" is the generic driver in -->
|
|
1693
|
+
<!-- pretext-common.xsl; the hooks here realize the pieces as blocks. -->
|
|
1694
|
+
|
|
1695
|
+
<!-- the block heading: run in to the introduction, else alone -->
|
|
1696
|
+
<xsl:template match="*" mode="present-tasks-introduction">
|
|
1697
|
+
<xsl:param name="b-has-statement"/>
|
|
1698
|
+
<xsl:param name="run-in-heading"/>
|
|
1699
|
+
<xsl:choose>
|
|
1700
|
+
<xsl:when test="$b-has-statement and introduction">
|
|
1701
|
+
<xsl:apply-templates select="introduction">
|
|
1702
|
+
<xsl:with-param name="run-in-heading" select="$run-in-heading"/>
|
|
1703
|
+
</xsl:apply-templates>
|
|
1704
|
+
</xsl:when>
|
|
1705
|
+
<xsl:otherwise>
|
|
1706
|
+
<fo:block keep-with-next.within-page="always">
|
|
1707
|
+
<xsl:copy-of select="$run-in-heading"/>
|
|
1708
|
+
</fo:block>
|
|
1709
|
+
</xsl:otherwise>
|
|
1710
|
+
</xsl:choose>
|
|
1711
|
+
</xsl:template>
|
|
1712
|
+
|
|
1713
|
+
<!-- one surviving task: an indented block, identified, then the guts -->
|
|
1714
|
+
<xsl:template match="task" mode="present-task-item">
|
|
1715
|
+
<xsl:param name="b-original"/>
|
|
1716
|
+
<xsl:param name="b-has-statement"/>
|
|
1717
|
+
<xsl:param name="b-has-hint"/>
|
|
1718
|
+
<xsl:param name="b-has-answer"/>
|
|
1719
|
+
<xsl:param name="b-has-solution"/>
|
|
1720
|
+
|
|
1721
|
+
<fo:block space-before="0.75em" space-after="0.75em">
|
|
1722
|
+
<!-- a sub-task indents one step deeper than its parent -->
|
|
1723
|
+
<xsl:attribute name="start-indent">
|
|
1724
|
+
<xsl:value-of select="count(ancestor-or-self::task) * $task-indentation"/>
|
|
1725
|
+
<xsl:text>em</xsl:text>
|
|
1726
|
+
</xsl:attribute>
|
|
1727
|
+
<!-- a duplicate (in a solutions division) cannot -->
|
|
1728
|
+
<!-- reuse the @id of the original -->
|
|
1729
|
+
<xsl:if test="$b-original">
|
|
1730
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
1731
|
+
</xsl:if>
|
|
1732
|
+
<xsl:variable name="heading">
|
|
1733
|
+
<fo:inline font-weight="bold" font-style="normal">
|
|
1734
|
+
<xsl:text>(</xsl:text>
|
|
1735
|
+
<xsl:apply-templates select="." mode="list-number"/>
|
|
1736
|
+
<xsl:text>)</xsl:text>
|
|
1737
|
+
<xsl:if test="title">
|
|
1738
|
+
<xsl:text> </xsl:text>
|
|
1739
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
1740
|
+
</xsl:if>
|
|
1741
|
+
</fo:inline>
|
|
1742
|
+
<xsl:text> </xsl:text>
|
|
1743
|
+
</xsl:variable>
|
|
1744
|
+
<xsl:apply-templates select="." mode="exercise-components">
|
|
1745
|
+
<xsl:with-param name="b-original" select="$b-original"/>
|
|
1746
|
+
<xsl:with-param name="b-has-statement" select="$b-has-statement"/>
|
|
1747
|
+
<xsl:with-param name="b-has-hint" select="$b-has-hint"/>
|
|
1748
|
+
<xsl:with-param name="b-has-answer" select="$b-has-answer"/>
|
|
1749
|
+
<xsl:with-param name="b-has-solution" select="$b-has-solution"/>
|
|
1750
|
+
<xsl:with-param name="run-in-heading" select="$heading"/>
|
|
1751
|
+
</xsl:apply-templates>
|
|
1752
|
+
</fo:block>
|
|
1753
|
+
</xsl:template>
|
|
1754
|
+
|
|
1755
|
+
<!-- the leaf form is driven from pretext-common.xsl; hooks here -->
|
|
1756
|
+
|
|
1757
|
+
<xsl:template match="*" mode="present-exercise-statement">
|
|
1758
|
+
<xsl:param name="run-in-heading"/>
|
|
1759
|
+
<xsl:apply-templates select="statement">
|
|
1760
|
+
<xsl:with-param name="run-in-heading" select="$run-in-heading"/>
|
|
1761
|
+
</xsl:apply-templates>
|
|
1762
|
+
<!-- a coding exercise's program rides with the statement -->
|
|
1763
|
+
<xsl:apply-templates select="program"/>
|
|
1764
|
+
</xsl:template>
|
|
1765
|
+
|
|
1766
|
+
<!-- a heading with no statement to carry it stands alone -->
|
|
1767
|
+
<xsl:template match="*" mode="present-exercise-statement-omitted">
|
|
1768
|
+
<xsl:param name="run-in-heading"/>
|
|
1769
|
+
<fo:block keep-with-next.within-page="always">
|
|
1770
|
+
<xsl:copy-of select="$run-in-heading"/>
|
|
1771
|
+
</fo:block>
|
|
1772
|
+
</xsl:template>
|
|
1773
|
+
|
|
1774
|
+
<!-- unstructured, a bare statement -->
|
|
1775
|
+
<xsl:template match="*" mode="present-exercise-statement-bare">
|
|
1776
|
+
<xsl:param name="run-in-heading"/>
|
|
1777
|
+
<xsl:call-template name="heading-then-content">
|
|
1778
|
+
<xsl:with-param name="heading" select="$run-in-heading"/>
|
|
1779
|
+
</xsl:call-template>
|
|
1780
|
+
</xsl:template>
|
|
1781
|
+
|
|
1782
|
+
<xsl:template match="*" mode="present-exercise-solutions">
|
|
1783
|
+
<xsl:param name="b-showing-hints"/>
|
|
1784
|
+
<xsl:param name="b-showing-answers"/>
|
|
1785
|
+
<xsl:param name="b-showing-solutions"/>
|
|
1786
|
+
<xsl:if test="$b-showing-hints">
|
|
1787
|
+
<xsl:apply-templates select="hint"/>
|
|
1788
|
+
</xsl:if>
|
|
1789
|
+
<xsl:if test="$b-showing-answers">
|
|
1790
|
+
<xsl:apply-templates select="answer"/>
|
|
1791
|
+
</xsl:if>
|
|
1792
|
+
<xsl:if test="$b-showing-solutions">
|
|
1793
|
+
<xsl:apply-templates select="solution"/>
|
|
1794
|
+
</xsl:if>
|
|
1795
|
+
</xsl:template>
|
|
1796
|
+
|
|
1797
|
+
<!-- ################### -->
|
|
1798
|
+
<!-- Solutions Divisions -->
|
|
1799
|
+
<!-- ################### -->
|
|
1800
|
+
|
|
1801
|
+
<!-- A "solutions" division has no children of its own: the -->
|
|
1802
|
+
<!-- solutions-generator of pretext-common.xsl mines content from -->
|
|
1803
|
+
<!-- the scoped divisions and calls back to the modal templates -->
|
|
1804
|
+
<!-- here. A division visited along the way repeats its heading; -->
|
|
1805
|
+
<!-- the generator supplies a stack of divisions needing mention. -->
|
|
1806
|
+
<xsl:template match="*" mode="duplicate-heading">
|
|
1807
|
+
<xsl:param name="heading-level"/>
|
|
1808
|
+
<xsl:param name="heading-stack" select="."/>
|
|
1809
|
+
<!-- Size by depth, matching the LaTeX "get-heading-text-size": -->
|
|
1810
|
+
<!-- the 11pt-class ratios for Huge/huge/Large/large/normalsize. -->
|
|
1811
|
+
<xsl:variable name="heading-size">
|
|
1812
|
+
<xsl:choose>
|
|
1813
|
+
<xsl:when test="$heading-level = 1">227%</xsl:when>
|
|
1814
|
+
<xsl:when test="$heading-level = 2">182%</xsl:when>
|
|
1815
|
+
<xsl:when test="$heading-level = 3">127%</xsl:when>
|
|
1816
|
+
<xsl:when test="$heading-level = 4">109%</xsl:when>
|
|
1817
|
+
<xsl:when test="$heading-level = 5">100%</xsl:when>
|
|
1818
|
+
<xsl:otherwise>100%</xsl:otherwise>
|
|
1819
|
+
</xsl:choose>
|
|
1820
|
+
</xsl:variable>
|
|
1821
|
+
<fo:block font-weight="bold"
|
|
1822
|
+
font-size="{$heading-size}"
|
|
1823
|
+
space-before="1.5em"
|
|
1824
|
+
space-after="0.75em"
|
|
1825
|
+
keep-with-next.within-page="always">
|
|
1826
|
+
<!-- Each division of the stack on its own line, as in the LaTeX -->
|
|
1827
|
+
<!-- conversion: the number and title joined by a middle dot, -->
|
|
1828
|
+
<!-- with no type-name. A division whose number is withheld -->
|
|
1829
|
+
<!-- (see "duplicate-heading-show-number") leads with the dot. -->
|
|
1830
|
+
<xsl:for-each select="$heading-stack">
|
|
1831
|
+
<fo:block>
|
|
1832
|
+
<xsl:variable name="show-number">
|
|
1833
|
+
<xsl:apply-templates select="." mode="duplicate-heading-show-number"/>
|
|
1834
|
+
</xsl:variable>
|
|
1835
|
+
<xsl:variable name="the-number">
|
|
1836
|
+
<xsl:apply-templates select="." mode="number"/>
|
|
1837
|
+
</xsl:variable>
|
|
1838
|
+
<xsl:if test="($show-number = 'true') and not($the-number = '')">
|
|
1839
|
+
<xsl:value-of select="$the-number"/>
|
|
1840
|
+
<xsl:text> </xsl:text>
|
|
1841
|
+
</xsl:if>
|
|
1842
|
+
<!-- MIDDLE DOT -->
|
|
1843
|
+
<xsl:text>· </xsl:text>
|
|
1844
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
1845
|
+
</fo:block>
|
|
1846
|
+
</xsl:for-each>
|
|
1847
|
+
</fo:block>
|
|
1848
|
+
</xsl:template>
|
|
1849
|
+
|
|
1850
|
+
<!-- One exercise (or project) in a solutions collection: gated -->
|
|
1851
|
+
<!-- by a dry run, since the switches may yield nothing; then a -->
|
|
1852
|
+
<!-- run-in heading and the chosen components. -->
|
|
1853
|
+
<xsl:template match="exercise[boolean(&INLINE-EXERCISE-FILTER;)]|&PROJECT-LIKE;|exercises//exercise|worksheet//exercise|reading-questions//exercise" mode="solutions">
|
|
1854
|
+
<xsl:param name="purpose"/>
|
|
1855
|
+
<xsl:param name="admit"/>
|
|
1856
|
+
<xsl:param name="b-component-heading"/>
|
|
1857
|
+
<xsl:param name="heading-level"/>
|
|
1858
|
+
<xsl:param name="b-has-statement"/>
|
|
1859
|
+
<xsl:param name="b-has-hint"/>
|
|
1860
|
+
<xsl:param name="b-has-answer"/>
|
|
1861
|
+
<xsl:param name="b-has-solution"/>
|
|
1862
|
+
<xsl:variable name="dry-run">
|
|
1863
|
+
<xsl:apply-templates select="." mode="dry-run">
|
|
1864
|
+
<xsl:with-param name="admit" select="$admit"/>
|
|
1865
|
+
<xsl:with-param name="b-has-statement" select="$b-has-statement"/>
|
|
1866
|
+
<xsl:with-param name="b-has-hint" select="$b-has-hint"/>
|
|
1867
|
+
<xsl:with-param name="b-has-answer" select="$b-has-answer"/>
|
|
1868
|
+
<xsl:with-param name="b-has-solution" select="$b-has-solution"/>
|
|
1869
|
+
</xsl:apply-templates>
|
|
1870
|
+
</xsl:variable>
|
|
1871
|
+
<xsl:if test="not($dry-run = '')">
|
|
1872
|
+
<fo:block space-before="1em" space-after="1em">
|
|
1873
|
+
<xsl:variable name="heading">
|
|
1874
|
+
<xsl:apply-templates select="." mode="exercise-heading"/>
|
|
1875
|
+
<xsl:text> </xsl:text>
|
|
1876
|
+
</xsl:variable>
|
|
1877
|
+
<!-- The duplicate's interior may contain objects (a -->
|
|
1878
|
+
<!-- "proof" in a "solution", display mathematics) that -->
|
|
1879
|
+
<!-- emit the same @id as their original rendering, and -->
|
|
1880
|
+
<!-- duplicated @ids are fatal to FOP. So the content -->
|
|
1881
|
+
<!-- is built as a fragment, then copied with every @id -->
|
|
1882
|
+
<!-- stripped; interior cross-references still target -->
|
|
1883
|
+
<!-- the originals. -->
|
|
1884
|
+
<xsl:variable name="duplicate-content">
|
|
1885
|
+
<xsl:apply-templates select="." mode="exercise-components">
|
|
1886
|
+
<xsl:with-param name="b-original" select="false()"/>
|
|
1887
|
+
<xsl:with-param name="b-has-statement" select="$b-has-statement"/>
|
|
1888
|
+
<xsl:with-param name="b-has-hint" select="$b-has-hint"/>
|
|
1889
|
+
<xsl:with-param name="b-has-answer" select="$b-has-answer"/>
|
|
1890
|
+
<xsl:with-param name="b-has-solution" select="$b-has-solution"/>
|
|
1891
|
+
<xsl:with-param name="run-in-heading" select="$heading"/>
|
|
1892
|
+
</xsl:apply-templates>
|
|
1893
|
+
</xsl:variable>
|
|
1894
|
+
<xsl:apply-templates select="exsl:node-set($duplicate-content)" mode="strip-id-attributes"/>
|
|
1895
|
+
</fo:block>
|
|
1896
|
+
</xsl:if>
|
|
1897
|
+
</xsl:template>
|
|
1898
|
+
|
|
1899
|
+
<!-- The identity copy, with the @id of formatting objects -->
|
|
1900
|
+
<!-- withheld. An @id interior to an SVG (a glyph definition, the -->
|
|
1901
|
+
<!-- target of a "use") must survive, or the drawing collapses; -->
|
|
1902
|
+
<!-- FOP only polices uniqueness of formatting object ids. -->
|
|
1903
|
+
<xsl:template match="node()|@*" mode="strip-id-attributes">
|
|
1904
|
+
<xsl:copy>
|
|
1905
|
+
<xsl:apply-templates select="node()|@*" mode="strip-id-attributes"/>
|
|
1906
|
+
</xsl:copy>
|
|
1907
|
+
</xsl:template>
|
|
1908
|
+
|
|
1909
|
+
<xsl:template match="fo:*/@id" mode="strip-id-attributes"/>
|
|
1910
|
+
|
|
1911
|
+
<!-- the wrappers pass everything through, with their prose -->
|
|
1912
|
+
<!-- gated on statements being shown -->
|
|
1913
|
+
<!-- Containers echoed in a "solutions" division: the generic -->
|
|
1914
|
+
<!-- driver in pretext-common.xsl decides if anything appears at -->
|
|
1915
|
+
<!-- all, and renders the items; the wrapping here -->
|
|
1916
|
+
|
|
1917
|
+
<xsl:template match="exercisegroup" mode="present-solutions-container">
|
|
1918
|
+
<xsl:param name="b-has-statement"/>
|
|
1919
|
+
<xsl:param name="content"/>
|
|
1920
|
+
|
|
1921
|
+
<xsl:if test="$b-has-statement">
|
|
1922
|
+
<xsl:apply-templates select="introduction"/>
|
|
1923
|
+
</xsl:if>
|
|
1924
|
+
<xsl:copy-of select="$content"/>
|
|
1925
|
+
<xsl:if test="$b-has-statement">
|
|
1926
|
+
<xsl:apply-templates select="conclusion"/>
|
|
1927
|
+
</xsl:if>
|
|
1928
|
+
</xsl:template>
|
|
1929
|
+
|
|
1930
|
+
<xsl:template match="subexercises" mode="present-solutions-container">
|
|
1931
|
+
<xsl:param name="b-has-statement"/>
|
|
1932
|
+
<xsl:param name="content"/>
|
|
1933
|
+
|
|
1934
|
+
<xsl:if test="title">
|
|
1935
|
+
<fo:block font-weight="bold"
|
|
1936
|
+
space-before="1em"
|
|
1937
|
+
space-after="0.5em"
|
|
1938
|
+
keep-with-next.within-page="always">
|
|
1939
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
1940
|
+
</fo:block>
|
|
1941
|
+
</xsl:if>
|
|
1942
|
+
<xsl:if test="$b-has-statement">
|
|
1943
|
+
<xsl:apply-templates select="introduction"/>
|
|
1944
|
+
</xsl:if>
|
|
1945
|
+
<xsl:copy-of select="$content"/>
|
|
1946
|
+
<xsl:if test="$b-has-statement">
|
|
1947
|
+
<xsl:apply-templates select="conclusion"/>
|
|
1948
|
+
</xsl:if>
|
|
1949
|
+
</xsl:template>
|
|
1950
|
+
|
|
1951
|
+
<!-- ##### -->
|
|
1952
|
+
<!-- Lists -->
|
|
1953
|
+
<!-- ##### -->
|
|
1954
|
+
|
|
1955
|
+
<!-- Ordered and unordered lists are fo:list-block constructions. -->
|
|
1956
|
+
<!-- The provisional label width is fixed, and generous; deep or -->
|
|
1957
|
+
<!-- wide markers (e.g. "xviii.") may eventually warrant a width -->
|
|
1958
|
+
<!-- computed from the actual labels. -->
|
|
1959
|
+
<xsl:template match="ol|ul">
|
|
1960
|
+
<xsl:choose>
|
|
1961
|
+
<!-- A "cols" request (2 to 6) lays the items out in that many -->
|
|
1962
|
+
<!-- equal columns. XSL-FO has no block-level multicolumn (only -->
|
|
1963
|
+
<!-- a page region carries "column-count"), so the columns are an -->
|
|
1964
|
+
<!-- fo:table, filled across each row, padding a short final row -->
|
|
1965
|
+
<!-- for the equal-width rows a tagged table needs (ISO 14289-1). -->
|
|
1966
|
+
<!-- Each cell is a one-item fo:list-block, so the marker shows -->
|
|
1967
|
+
<!-- and the item keeps "L"/"LI" structure for a screen reader -->
|
|
1968
|
+
<!-- despite the table layout. -->
|
|
1969
|
+
<xsl:when test="@cols">
|
|
1970
|
+
<xsl:variable name="cols" select="@cols"/>
|
|
1971
|
+
<fo:table table-layout="fixed" width="100%" space-before="0.5em" space-after="0.5em">
|
|
1972
|
+
<xsl:call-template name="equal-table-columns">
|
|
1973
|
+
<xsl:with-param name="remaining" select="$cols"/>
|
|
1974
|
+
</xsl:call-template>
|
|
1975
|
+
<fo:table-body>
|
|
1976
|
+
<xsl:for-each select="li[(position() mod $cols) = 1]">
|
|
1977
|
+
<fo:table-row>
|
|
1978
|
+
<xsl:variable name="row-items" select=".|following-sibling::li[position() < $cols]"/>
|
|
1979
|
+
<xsl:for-each select="$row-items">
|
|
1980
|
+
<fo:table-cell padding-right="6pt">
|
|
1981
|
+
<fo:list-block provisional-distance-between-starts="2em"
|
|
1982
|
+
provisional-label-separation="0.25em">
|
|
1983
|
+
<xsl:apply-templates select="."/>
|
|
1984
|
+
</fo:list-block>
|
|
1985
|
+
</fo:table-cell>
|
|
1986
|
+
</xsl:for-each>
|
|
1987
|
+
<xsl:call-template name="empty-table-cells">
|
|
1988
|
+
<xsl:with-param name="remaining" select="$cols - count($row-items)"/>
|
|
1989
|
+
</xsl:call-template>
|
|
1990
|
+
</fo:table-row>
|
|
1991
|
+
</xsl:for-each>
|
|
1992
|
+
</fo:table-body>
|
|
1993
|
+
</fo:table>
|
|
1994
|
+
</xsl:when>
|
|
1995
|
+
<xsl:otherwise>
|
|
1996
|
+
<fo:list-block provisional-distance-between-starts="2em"
|
|
1997
|
+
provisional-label-separation="0.25em"
|
|
1998
|
+
space-before="0.5em"
|
|
1999
|
+
space-after="0.5em">
|
|
2000
|
+
<xsl:apply-templates select="li"/>
|
|
2001
|
+
</fo:list-block>
|
|
2002
|
+
</xsl:otherwise>
|
|
2003
|
+
</xsl:choose>
|
|
2004
|
+
</xsl:template>
|
|
2005
|
+
|
|
2006
|
+
<xsl:template match="ol/li|ul/li">
|
|
2007
|
+
<fo:list-item>
|
|
2008
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
2009
|
+
<fo:list-item-label end-indent="label-end()">
|
|
2010
|
+
<fo:block text-align="end">
|
|
2011
|
+
<xsl:apply-templates select="." mode="list-label"/>
|
|
2012
|
+
</fo:block>
|
|
2013
|
+
</fo:list-item-label>
|
|
2014
|
+
<fo:list-item-body start-indent="body-start()">
|
|
2015
|
+
<xsl:apply-templates select="." mode="list-item-content"/>
|
|
2016
|
+
</fo:list-item-body>
|
|
2017
|
+
</fo:list-item>
|
|
2018
|
+
</xsl:template>
|
|
2019
|
+
|
|
2020
|
+
<!-- The assembly stylesheet stamps every "ol" with @format-code -->
|
|
2021
|
+
<!-- ('1', 'a', 'A', 'i', 'I', or '0' for a zero-based list), and -->
|
|
2022
|
+
<!-- with @marker-prefix and @marker-suffix adornments, all -->
|
|
2023
|
+
<!-- deconstructed from any authored @marker. -->
|
|
2024
|
+
<xsl:template match="ol/li" mode="list-label">
|
|
2025
|
+
<xsl:variable name="the-position" select="count(preceding-sibling::li) + 1"/>
|
|
2026
|
+
<xsl:value-of select="parent::ol/@marker-prefix"/>
|
|
2027
|
+
<xsl:choose>
|
|
2028
|
+
<!-- a zero-based list counts from zero, in arabic numerals -->
|
|
2029
|
+
<xsl:when test="parent::ol/@format-code = '0'">
|
|
2030
|
+
<xsl:number value="$the-position - 1" format="1"/>
|
|
2031
|
+
</xsl:when>
|
|
2032
|
+
<xsl:otherwise>
|
|
2033
|
+
<xsl:number value="$the-position" format="{parent::ol/@format-code}"/>
|
|
2034
|
+
</xsl:otherwise>
|
|
2035
|
+
</xsl:choose>
|
|
2036
|
+
<xsl:value-of select="parent::ol/@marker-suffix"/>
|
|
2037
|
+
</xsl:template>
|
|
2038
|
+
|
|
2039
|
+
<!-- Bullets via the "format-code" machinery of pretext-common.xsl, -->
|
|
2040
|
+
<!-- which cycles disc, circle, square by level, and honors an -->
|
|
2041
|
+
<!-- authored @marker (the empty @marker giving no bullet at all). -->
|
|
2042
|
+
<xsl:template match="ul/li" mode="list-label">
|
|
2043
|
+
<xsl:variable name="format-code">
|
|
2044
|
+
<xsl:apply-templates select="parent::ul" mode="format-code"/>
|
|
2045
|
+
</xsl:variable>
|
|
2046
|
+
<xsl:choose>
|
|
2047
|
+
<xsl:when test="$format-code = 'disc'">
|
|
2048
|
+
<xsl:text>•</xsl:text>
|
|
2049
|
+
</xsl:when>
|
|
2050
|
+
<xsl:when test="$format-code = 'circle'">
|
|
2051
|
+
<xsl:text>◦</xsl:text>
|
|
2052
|
+
</xsl:when>
|
|
2053
|
+
<xsl:when test="$format-code = 'square'">
|
|
2054
|
+
<xsl:text>▪</xsl:text>
|
|
2055
|
+
</xsl:when>
|
|
2056
|
+
<!-- 'none' -->
|
|
2057
|
+
<xsl:otherwise/>
|
|
2058
|
+
</xsl:choose>
|
|
2059
|
+
</xsl:template>
|
|
2060
|
+
|
|
2061
|
+
<!-- Any of these children indicates a structured list item, -->
|
|
2062
|
+
<!-- per the schema; otherwise the item is mixed content, set -->
|
|
2063
|
+
<!-- as a single paragraph. -->
|
|
2064
|
+
<xsl:template match="li" mode="list-item-content">
|
|
2065
|
+
<!-- An optional title leads as an italic heading line, kept with the content that follows -->
|
|
2066
|
+
<xsl:if test="title">
|
|
2067
|
+
<fo:block font-style="italic" keep-with-next.within-page="always">
|
|
2068
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
2069
|
+
</fo:block>
|
|
2070
|
+
</xsl:if>
|
|
2071
|
+
<xsl:choose>
|
|
2072
|
+
<xsl:when test="p|blockquote|pre|image|video|program|console|tabular|&FIGURE-LIKE;|&ASIDE-LIKE;|sidebyside|sbsgroup|sage">
|
|
2073
|
+
<xsl:apply-templates select="*[not(self::title)]"/>
|
|
2074
|
+
</xsl:when>
|
|
2075
|
+
<xsl:otherwise>
|
|
2076
|
+
<fo:block text-align="{$text-alignment}" space-after="0.5em">
|
|
2077
|
+
<xsl:apply-templates select="node()[not(self::title)]"/>
|
|
2078
|
+
</fo:block>
|
|
2079
|
+
</xsl:otherwise>
|
|
2080
|
+
</xsl:choose>
|
|
2081
|
+
</xsl:template>
|
|
2082
|
+
|
|
2083
|
+
<!-- A description list lays out each item in two columns: a -->
|
|
2084
|
+
<!-- bold title in a label column, then its content. The -->
|
|
2085
|
+
<!-- "@width" hint sizes that label column; a narrow one -->
|
|
2086
|
+
<!-- flush-lefts its title, the others flush-right. -->
|
|
2087
|
+
<xsl:template match="dl">
|
|
2088
|
+
<xsl:variable name="label-width">
|
|
2089
|
+
<xsl:choose>
|
|
2090
|
+
<xsl:when test="@width = 'narrow'">6em</xsl:when>
|
|
2091
|
+
<xsl:when test="@width = 'wide'">14em</xsl:when>
|
|
2092
|
+
<!-- 'medium', the default, and any typo (the schema checks) -->
|
|
2093
|
+
<xsl:otherwise>10em</xsl:otherwise>
|
|
2094
|
+
</xsl:choose>
|
|
2095
|
+
</xsl:variable>
|
|
2096
|
+
<fo:list-block provisional-distance-between-starts="{$label-width}"
|
|
2097
|
+
provisional-label-separation="1em"
|
|
2098
|
+
space-before="0.5em"
|
|
2099
|
+
space-after="0.5em">
|
|
2100
|
+
<xsl:apply-templates select="li"/>
|
|
2101
|
+
</fo:list-block>
|
|
2102
|
+
</xsl:template>
|
|
2103
|
+
|
|
2104
|
+
<xsl:template match="dl/li">
|
|
2105
|
+
<xsl:variable name="label-align">
|
|
2106
|
+
<xsl:choose>
|
|
2107
|
+
<xsl:when test="parent::dl/@width = 'narrow'">start</xsl:when>
|
|
2108
|
+
<xsl:otherwise>end</xsl:otherwise>
|
|
2109
|
+
</xsl:choose>
|
|
2110
|
+
</xsl:variable>
|
|
2111
|
+
<fo:list-item space-before="0.5em">
|
|
2112
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
2113
|
+
<fo:list-item-label end-indent="label-end()">
|
|
2114
|
+
<fo:block font-weight="bold" text-align="{$label-align}">
|
|
2115
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
2116
|
+
</fo:block>
|
|
2117
|
+
</fo:list-item-label>
|
|
2118
|
+
<fo:list-item-body start-indent="body-start()">
|
|
2119
|
+
<xsl:apply-templates select="*[not(self::title)]"/>
|
|
2120
|
+
</fo:list-item-body>
|
|
2121
|
+
</fo:list-item>
|
|
2122
|
+
</xsl:template>
|
|
2123
|
+
|
|
2124
|
+
<!-- ###### -->
|
|
2125
|
+
<!-- Images -->
|
|
2126
|
+
<!-- ###### -->
|
|
2127
|
+
|
|
2128
|
+
<!-- An image is a centered block, with the authored @width -->
|
|
2129
|
+
<!-- percentage (or the documented defaults) honored by the -->
|
|
2130
|
+
<!-- common machinery, which makes an image fill its panel when -->
|
|
2131
|
+
<!-- inside a "sidebyside". The percentage width of the graphic -->
|
|
2132
|
+
<!-- is relative to the available width, and the image scales to -->
|
|
2133
|
+
<!-- it, preserving the aspect ratio. Restricted to externally -->
|
|
2134
|
+
<!-- provided and pre-generated images; the harness reports the -->
|
|
2135
|
+
<!-- born-in-source kinds (e.g. "latex-image"), which need -->
|
|
2136
|
+
<!-- companion image-generation components. N.B. an SVG file -->
|
|
2137
|
+
<!-- must carry its intrinsic @width and @height: with only a -->
|
|
2138
|
+
<!-- @viewBox, FOP assumes a square, and the drawing floats in -->
|
|
2139
|
+
<!-- extra vertical space. -->
|
|
2140
|
+
<xsl:template match="image[@source|@pi:generated]|image[latex-image]|image[sageplot]|image[asymptote]|image[pf:prefigure]|image[mermaid]">
|
|
2141
|
+
<xsl:variable name="width">
|
|
2142
|
+
<xsl:apply-templates select="." mode="get-width-percentage"/>
|
|
2143
|
+
</xsl:variable>
|
|
2144
|
+
<fo:block text-align="center" space-before="0.5em" space-after="0.5em">
|
|
2145
|
+
<fo:external-graphic width="{$width}"
|
|
2146
|
+
content-width="scale-to-fit"
|
|
2147
|
+
scaling="uniform">
|
|
2148
|
+
<xsl:choose>
|
|
2149
|
+
<!-- a decorative image wants to be a PDF "artifact", -->
|
|
2150
|
+
<!-- invisible to assistive technology; FOP has no -->
|
|
2151
|
+
<!-- mechanism yet, so it gets empty alternate text -->
|
|
2152
|
+
<xsl:when test="@decorative = 'yes'">
|
|
2153
|
+
<xsl:attribute name="fox:alt-text"/>
|
|
2154
|
+
</xsl:when>
|
|
2155
|
+
<!-- authored alternate text, as PDF/UA requires of -->
|
|
2156
|
+
<!-- any figure; absent it, FOP will complain -->
|
|
2157
|
+
<xsl:when test="shortdescription">
|
|
2158
|
+
<xsl:attribute name="fox:alt-text">
|
|
2159
|
+
<xsl:value-of select="normalize-space(shortdescription)"/>
|
|
2160
|
+
</xsl:attribute>
|
|
2161
|
+
</xsl:when>
|
|
2162
|
+
<xsl:otherwise/>
|
|
2163
|
+
</xsl:choose>
|
|
2164
|
+
<xsl:attribute name="src">
|
|
2165
|
+
<xsl:text>url(</xsl:text>
|
|
2166
|
+
<xsl:apply-templates select="." mode="image-filename"/>
|
|
2167
|
+
<xsl:text>)</xsl:text>
|
|
2168
|
+
</xsl:attribute>
|
|
2169
|
+
</fo:external-graphic>
|
|
2170
|
+
</fo:block>
|
|
2171
|
+
</xsl:template>
|
|
2172
|
+
|
|
2173
|
+
<!-- The filename, relative to the directory where FOP runs: the -->
|
|
2174
|
+
<!-- managed external or generated directory, the indicated file, -->
|
|
2175
|
+
<!-- and an absent extension means a manufactured SVG (all the -->
|
|
2176
|
+
<!-- HTML conversion model). -->
|
|
2177
|
+
<xsl:template match="image[@source|@pi:generated]" mode="image-filename">
|
|
2178
|
+
<xsl:variable name="location">
|
|
2179
|
+
<xsl:choose>
|
|
2180
|
+
<xsl:when test="@pi:generated">
|
|
2181
|
+
<xsl:value-of select="$generated-directory"/>
|
|
2182
|
+
<xsl:value-of select="@pi:generated"/>
|
|
2183
|
+
</xsl:when>
|
|
2184
|
+
<xsl:otherwise>
|
|
2185
|
+
<xsl:value-of select="$external-directory"/>
|
|
2186
|
+
<xsl:value-of select="@source"/>
|
|
2187
|
+
</xsl:otherwise>
|
|
2188
|
+
</xsl:choose>
|
|
2189
|
+
</xsl:variable>
|
|
2190
|
+
<xsl:variable name="extension">
|
|
2191
|
+
<xsl:call-template name="file-extension">
|
|
2192
|
+
<xsl:with-param name="filename" select="$location"/>
|
|
2193
|
+
</xsl:call-template>
|
|
2194
|
+
</xsl:variable>
|
|
2195
|
+
<xsl:value-of select="$location"/>
|
|
2196
|
+
<xsl:if test="$extension = ''">
|
|
2197
|
+
<xsl:text>.svg</xsl:text>
|
|
2198
|
+
</xsl:if>
|
|
2199
|
+
</xsl:template>
|
|
2200
|
+
|
|
2201
|
+
<!-- Born-in-source images live in kind-specific subdirectories -->
|
|
2202
|
+
<!-- of the generated directory, with filenames decided by the -->
|
|
2203
|
+
<!-- "image-source-basename" machinery, as manufactured SVG; -->
|
|
2204
|
+
<!-- companion generation components produce the files. (A 3-D -->
|
|
2205
|
+
<!-- "sageplot" has no useful print representation yet.) -->
|
|
2206
|
+
<xsl:template match="image[latex-image]|image[sageplot]|image[asymptote]|image[pf:prefigure]|image[mermaid]" mode="image-filename">
|
|
2207
|
+
<xsl:value-of select="$generated-directory"/>
|
|
2208
|
+
<xsl:if test="$b-managed-directories">
|
|
2209
|
+
<xsl:choose>
|
|
2210
|
+
<xsl:when test="latex-image">
|
|
2211
|
+
<xsl:text>latex-image/</xsl:text>
|
|
2212
|
+
</xsl:when>
|
|
2213
|
+
<xsl:when test="sageplot">
|
|
2214
|
+
<xsl:text>sageplot/</xsl:text>
|
|
2215
|
+
</xsl:when>
|
|
2216
|
+
<xsl:when test="asymptote">
|
|
2217
|
+
<xsl:text>asymptote/</xsl:text>
|
|
2218
|
+
</xsl:when>
|
|
2219
|
+
<xsl:when test="pf:prefigure">
|
|
2220
|
+
<xsl:text>prefigure/</xsl:text>
|
|
2221
|
+
</xsl:when>
|
|
2222
|
+
<xsl:when test="mermaid">
|
|
2223
|
+
<xsl:text>mermaid/</xsl:text>
|
|
2224
|
+
</xsl:when>
|
|
2225
|
+
</xsl:choose>
|
|
2226
|
+
</xsl:if>
|
|
2227
|
+
<xsl:apply-templates select="latex-image|sageplot|asymptote|pf:prefigure|mermaid" mode="image-source-basename"/>
|
|
2228
|
+
<xsl:choose>
|
|
2229
|
+
<xsl:when test="pf:prefigure">
|
|
2230
|
+
<xsl:text>-11.svg</xsl:text>
|
|
2231
|
+
</xsl:when>
|
|
2232
|
+
<xsl:otherwise>
|
|
2233
|
+
<xsl:text>.svg</xsl:text>
|
|
2234
|
+
</xsl:otherwise>
|
|
2235
|
+
</xsl:choose>
|
|
2236
|
+
</xsl:template>
|
|
2237
|
+
|
|
2238
|
+
<!-- ###### -->
|
|
2239
|
+
<!-- Tables -->
|
|
2240
|
+
<!-- ###### -->
|
|
2241
|
+
|
|
2242
|
+
<!-- A PreTeXt "tabular" is an fo:table. FOP only implements the -->
|
|
2243
|
+
<!-- fixed table layout, so it cannot size columns to content the -->
|
|
2244
|
+
<!-- way LaTeX does; instead the converter estimates a natural -->
|
|
2245
|
+
<!-- width for each column (see "tabular-column-widths"), sums them -->
|
|
2246
|
+
<!-- to a natural table width, and claims that as a percentage of -->
|
|
2247
|
+
<!-- the text width, centering the result. A table whose content -->
|
|
2248
|
+
<!-- needs the whole text width (or more) falls back to the full -->
|
|
2249
|
+
<!-- width. The estimates also serve as the proportional column -->
|
|
2250
|
+
<!-- widths, so the columns keep their relative sizes. Header rows, -->
|
|
2251
|
+
<!-- horizontal or vertical (rotated), land in an fo:table-header, -->
|
|
2252
|
+
<!-- which FOP tags as "TH" cells in the PDF structure tree, as -->
|
|
2253
|
+
<!-- PDF/UA requires. The @row-headers request bolds the leading -->
|
|
2254
|
+
<!-- column; FOP can mark only an fo:table-header as "TH", so those -->
|
|
2255
|
+
<!-- cells stay "TD" in the structure tree, a known FOP limit. -->
|
|
2256
|
+
<xsl:template match="tabular">
|
|
2257
|
+
<xsl:variable name="column-count">
|
|
2258
|
+
<xsl:apply-templates select="." mode="column-count"/>
|
|
2259
|
+
</xsl:variable>
|
|
2260
|
+
<xsl:variable name="widths-rtf">
|
|
2261
|
+
<xsl:call-template name="tabular-column-widths">
|
|
2262
|
+
<xsl:with-param name="count" select="number($column-count)"/>
|
|
2263
|
+
</xsl:call-template>
|
|
2264
|
+
</xsl:variable>
|
|
2265
|
+
<xsl:variable name="widths" select="exsl:node-set($widths-rtf)/w"/>
|
|
2266
|
+
<xsl:variable name="natural-width" select="sum($widths)"/>
|
|
2267
|
+
<!-- the natural width as a percentage of the text width, but -->
|
|
2268
|
+
<!-- never wider than the full text width. A table in a -->
|
|
2269
|
+
<!-- "sidebyside" panel fills the panel: the panel width, not the -->
|
|
2270
|
+
<!-- text width, is its reference, and it is unknown here, so the -->
|
|
2271
|
+
<!-- estimate only orders the columns (still proportional below). -->
|
|
2272
|
+
<xsl:variable name="table-percent">
|
|
2273
|
+
<xsl:choose>
|
|
2274
|
+
<xsl:when test="ancestor::sidebyside">
|
|
2275
|
+
<xsl:text>100</xsl:text>
|
|
2276
|
+
</xsl:when>
|
|
2277
|
+
<xsl:when test="$natural-width >= $text-width-points">
|
|
2278
|
+
<xsl:text>100</xsl:text>
|
|
2279
|
+
</xsl:when>
|
|
2280
|
+
<xsl:otherwise>
|
|
2281
|
+
<xsl:value-of select="round($natural-width * 100 div $text-width-points)"/>
|
|
2282
|
+
</xsl:otherwise>
|
|
2283
|
+
</xsl:choose>
|
|
2284
|
+
</xsl:variable>
|
|
2285
|
+
<!-- center a less-than-full-width table by indenting both edges -->
|
|
2286
|
+
<!-- half of the leftover width each (FOP supports no "auto" -->
|
|
2287
|
+
<!-- margin, and derives the width from the indents, so both are -->
|
|
2288
|
+
<!-- set to keep the table centered rather than stretched right). -->
|
|
2289
|
+
<xsl:variable name="side-indent" select="round((100 - $table-percent) div 2)"/>
|
|
2290
|
+
<!-- Keep a "tabular" whole on a page when it fits there, so one -->
|
|
2291
|
+
<!-- that would otherwise split at a page boundary moves forward -->
|
|
2292
|
+
<!-- intact. This matches LaTeX, where a tabular sits inside an -->
|
|
2293
|
+
<!-- unbreakable tcolorbox. A finite keep strength (not the -->
|
|
2294
|
+
<!-- forcing "always") lets FOP override it and break a tabular -->
|
|
2295
|
+
<!-- too tall for one page, rather than overflow and clip it as -->
|
|
2296
|
+
<!-- "always" would. Tune the strength if the keeping proves -->
|
|
2297
|
+
<!-- too eager or too weak. -->
|
|
2298
|
+
<fo:table table-layout="fixed" space-before="0.75em" space-after="0.75em" keep-together.within-page="5">
|
|
2299
|
+
<xsl:choose>
|
|
2300
|
+
<!-- In a "sidebyside" panel a table takes its natural width -->
|
|
2301
|
+
<!-- (in points), so its rules stay coextensive with the -->
|
|
2302
|
+
<!-- content instead of stretching to fill the panel and -->
|
|
2303
|
+
<!-- trailing an over-long top rule. Capped at the text -->
|
|
2304
|
+
<!-- measure so it never overflows the page; a panel narrower -->
|
|
2305
|
+
<!-- than the natural width is uncommon and would only crowd -->
|
|
2306
|
+
<!-- a neighbor, not run off the page. -->
|
|
2307
|
+
<xsl:when test="ancestor::sidebyside">
|
|
2308
|
+
<xsl:attribute name="width">
|
|
2309
|
+
<xsl:choose>
|
|
2310
|
+
<xsl:when test="$natural-width > $text-width-points">
|
|
2311
|
+
<xsl:value-of select="format-number($text-width-points, '0.##')"/>
|
|
2312
|
+
</xsl:when>
|
|
2313
|
+
<xsl:otherwise>
|
|
2314
|
+
<xsl:value-of select="format-number($natural-width, '0.##')"/>
|
|
2315
|
+
</xsl:otherwise>
|
|
2316
|
+
</xsl:choose>
|
|
2317
|
+
<xsl:text>pt</xsl:text>
|
|
2318
|
+
</xsl:attribute>
|
|
2319
|
+
</xsl:when>
|
|
2320
|
+
<xsl:otherwise>
|
|
2321
|
+
<xsl:attribute name="width">
|
|
2322
|
+
<xsl:value-of select="$table-percent"/>
|
|
2323
|
+
<xsl:text>%</xsl:text>
|
|
2324
|
+
</xsl:attribute>
|
|
2325
|
+
<xsl:attribute name="start-indent">
|
|
2326
|
+
<xsl:value-of select="$side-indent"/>
|
|
2327
|
+
<xsl:text>%</xsl:text>
|
|
2328
|
+
</xsl:attribute>
|
|
2329
|
+
<xsl:attribute name="end-indent">
|
|
2330
|
+
<xsl:value-of select="$side-indent"/>
|
|
2331
|
+
<xsl:text>%</xsl:text>
|
|
2332
|
+
</xsl:attribute>
|
|
2333
|
+
</xsl:otherwise>
|
|
2334
|
+
</xsl:choose>
|
|
2335
|
+
<!-- Every rule, interior or perimeter, is drawn per cell in the -->
|
|
2336
|
+
<!-- "cell" template from the effective edge weights resolved in -->
|
|
2337
|
+
<!-- -common (cell, then row/col, then whole-tabular), so no -->
|
|
2338
|
+
<!-- table-wide border is placed here. -->
|
|
2339
|
+
<xsl:for-each select="$widths">
|
|
2340
|
+
<fo:table-column column-width="proportional-column-width({.})"/>
|
|
2341
|
+
</xsl:for-each>
|
|
2342
|
+
<xsl:if test="row[(@header = 'yes') or (@header = 'vertical')]">
|
|
2343
|
+
<fo:table-header>
|
|
2344
|
+
<xsl:apply-templates select="row[(@header = 'yes') or (@header = 'vertical')]"/>
|
|
2345
|
+
</fo:table-header>
|
|
2346
|
+
</xsl:if>
|
|
2347
|
+
<fo:table-body>
|
|
2348
|
+
<xsl:apply-templates select="row[not(@header = 'yes') and not(@header = 'vertical')]"/>
|
|
2349
|
+
</fo:table-body>
|
|
2350
|
+
</fo:table>
|
|
2351
|
+
</xsl:template>
|
|
2352
|
+
|
|
2353
|
+
<!-- An estimated width, in points, for each of a tabular's columns, -->
|
|
2354
|
+
<!-- emitted as a "w" element apiece. A column whose cells hold -->
|
|
2355
|
+
<!-- paragraphs takes a fraction of the text width: its authored -->
|
|
2356
|
+
<!-- "col/@width", else a default fraction (mirroring the LaTeX -->
|
|
2357
|
+
<!-- converter, which a paragraph needs a settled width to wrap in). -->
|
|
2358
|
+
<!-- Every other column is measured from its widest piece of content -->
|
|
2359
|
+
<!-- among the rows that span no columns: the longest "line", the -->
|
|
2360
|
+
<!-- longest line-free cell, or the longest visual URL. Seven points -->
|
|
2361
|
+
<!-- per character plus padding is a deliberately generous estimate -->
|
|
2362
|
+
<!-- (a capital or digit in the serif font runs near that wide), so -->
|
|
2363
|
+
<!-- content is unlikely to overflow its column. -->
|
|
2364
|
+
<xsl:template name="tabular-column-widths">
|
|
2365
|
+
<xsl:param name="count"/>
|
|
2366
|
+
<xsl:param name="index" select="1"/>
|
|
2367
|
+
<xsl:if test="$index <= $count">
|
|
2368
|
+
<!-- Size from the cells in column "index" of rows that hold the -->
|
|
2369
|
+
<!-- full column-count (so cell position maps to column number), -->
|
|
2370
|
+
<!-- skipping rows with a colspan. When no row is that full (a -->
|
|
2371
|
+
<!-- "tabular" with more "col" than cells in any row), fall back -->
|
|
2372
|
+
<!-- to the same column of every colspan-free row, so the present -->
|
|
2373
|
+
<!-- columns still size from their content and only a genuinely -->
|
|
2374
|
+
<!-- empty column is left with nothing. -->
|
|
2375
|
+
<xsl:variable name="full-row-cells" select="row[(count(cell) = $count) and not(cell/@colspan)]/cell[$index]"/>
|
|
2376
|
+
<xsl:variable name="column-cells" select="$full-row-cells | row[not($full-row-cells) and not(cell/@colspan)]/cell[$index]"/>
|
|
2377
|
+
<w>
|
|
2378
|
+
<xsl:choose>
|
|
2379
|
+
<!-- a paragraph column: a fraction of the text width -->
|
|
2380
|
+
<xsl:when test="$column-cells/p">
|
|
2381
|
+
<xsl:variable name="fraction">
|
|
2382
|
+
<xsl:choose>
|
|
2383
|
+
<xsl:when test="col[$index]/@width">
|
|
2384
|
+
<xsl:value-of select="substring-before(col[$index]/@width, '%') div 100"/>
|
|
2385
|
+
</xsl:when>
|
|
2386
|
+
<xsl:otherwise>
|
|
2387
|
+
<xsl:text>0.2</xsl:text>
|
|
2388
|
+
</xsl:otherwise>
|
|
2389
|
+
</xsl:choose>
|
|
2390
|
+
</xsl:variable>
|
|
2391
|
+
<xsl:value-of select="round($fraction * $text-width-points)"/>
|
|
2392
|
+
</xsl:when>
|
|
2393
|
+
<!-- a natural column: measured from its widest content; -->
|
|
2394
|
+
<!-- a footnote's text is set elsewhere, not in the cell, -->
|
|
2395
|
+
<!-- so it does not count toward the column's width -->
|
|
2396
|
+
<xsl:otherwise>
|
|
2397
|
+
<!-- the character count of each candidate's displayed -->
|
|
2398
|
+
<!-- text (see "width-text"), gathered so the widest can -->
|
|
2399
|
+
<!-- be taken; a template call cannot live in a sort key -->
|
|
2400
|
+
<xsl:variable name="lengths-rtf">
|
|
2401
|
+
<xsl:for-each select="$column-cells/line | $column-cells[not(line)] | $column-cells//url/@visual">
|
|
2402
|
+
<xsl:variable name="displayed">
|
|
2403
|
+
<xsl:apply-templates select="." mode="width-text"/>
|
|
2404
|
+
</xsl:variable>
|
|
2405
|
+
<length>
|
|
2406
|
+
<xsl:value-of select="string-length(normalize-space($displayed))"/>
|
|
2407
|
+
</length>
|
|
2408
|
+
</xsl:for-each>
|
|
2409
|
+
</xsl:variable>
|
|
2410
|
+
<xsl:variable name="longest">
|
|
2411
|
+
<xsl:for-each select="exsl:node-set($lengths-rtf)/length">
|
|
2412
|
+
<xsl:sort select="number(.)" data-type="number" order="descending"/>
|
|
2413
|
+
<xsl:if test="position() = 1">
|
|
2414
|
+
<xsl:value-of select="."/>
|
|
2415
|
+
</xsl:if>
|
|
2416
|
+
</xsl:for-each>
|
|
2417
|
+
</xsl:variable>
|
|
2418
|
+
<xsl:choose>
|
|
2419
|
+
<!-- a genuinely empty column (no cell of any row sits -->
|
|
2420
|
+
<!-- here, e.g. a "col" beyond the cells a row supplies) -->
|
|
2421
|
+
<!-- takes only the padding, so a table-wide top or -->
|
|
2422
|
+
<!-- bottom rule does not trail past the real content; -->
|
|
2423
|
+
<!-- the value is the formula below at zero length. -->
|
|
2424
|
+
<xsl:when test="$longest = ''">
|
|
2425
|
+
<xsl:value-of select="8"/>
|
|
2426
|
+
</xsl:when>
|
|
2427
|
+
<xsl:otherwise>
|
|
2428
|
+
<xsl:value-of select="7 * $longest + 8"/>
|
|
2429
|
+
</xsl:otherwise>
|
|
2430
|
+
</xsl:choose>
|
|
2431
|
+
</xsl:otherwise>
|
|
2432
|
+
</xsl:choose>
|
|
2433
|
+
</w>
|
|
2434
|
+
<xsl:call-template name="tabular-column-widths">
|
|
2435
|
+
<xsl:with-param name="count" select="$count"/>
|
|
2436
|
+
<xsl:with-param name="index" select="$index + 1"/>
|
|
2437
|
+
</xsl:call-template>
|
|
2438
|
+
</xsl:if>
|
|
2439
|
+
</xsl:template>
|
|
2440
|
+
|
|
2441
|
+
<!-- The text a table column is sized from. By default this -->
|
|
2442
|
+
<!-- copy recurses, so wrapper elements, and the source text of -->
|
|
2443
|
+
<!-- an "m" (a fair proxy for the rendered math), are measured, -->
|
|
2444
|
+
<!-- while a footnote is dropped (its text is set outside the -->
|
|
2445
|
+
<!-- cell). A generator, though, makes text the source lacks, -->
|
|
2446
|
+
<!-- so it is rendered to that text and the result measured: an -->
|
|
2447
|
+
<!-- "xref" (its reference text), the TeX-family and -->
|
|
2448
|
+
<!-- PreTeXt/WeBWorK logos, the date and time, the Latin -->
|
|
2449
|
+
<!-- abbreviations, a "url" (whose text may be an attribute), -->
|
|
2450
|
+
<!-- the tag-syntax elements, and the punctuation and symbol -->
|
|
2451
|
+
<!-- characters. A "fillin" contributes its blank's character -->
|
|
2452
|
+
<!-- count. Text and attribute nodes fall to the built-in -->
|
|
2453
|
+
<!-- rules, which copy their string value through. -->
|
|
2454
|
+
<xsl:template match="*" mode="width-text">
|
|
2455
|
+
<xsl:apply-templates select="node()" mode="width-text"/>
|
|
2456
|
+
</xsl:template>
|
|
2457
|
+
|
|
2458
|
+
<xsl:template match="fn" mode="width-text"/>
|
|
2459
|
+
|
|
2460
|
+
<!-- A cross-reference's displayed text is generated, never in -->
|
|
2461
|
+
<!-- the source, so render it via the shared "xref-text" (driven -->
|
|
2462
|
+
<!-- by the resolved text style) rather than measure an empty -->
|
|
2463
|
+
<!-- string; "self-referential-tabular-xref" is the witness. -->
|
|
2464
|
+
<xsl:template match="xref" mode="width-text">
|
|
2465
|
+
<xsl:variable name="text-style">
|
|
2466
|
+
<xsl:apply-templates select="." mode="get-text-style"/>
|
|
2467
|
+
</xsl:variable>
|
|
2468
|
+
<xsl:apply-templates select="." mode="xref-text">
|
|
2469
|
+
<xsl:with-param name="target" select="id(@ref)"/>
|
|
2470
|
+
<xsl:with-param name="text-style" select="$text-style"/>
|
|
2471
|
+
</xsl:apply-templates>
|
|
2472
|
+
</xsl:template>
|
|
2473
|
+
|
|
2474
|
+
<!-- The remaining generators have a normal template that already -->
|
|
2475
|
+
<!-- emits their displayed text, so render each in place; their -->
|
|
2476
|
+
<!-- output is plain text (or text inside an inline), which the -->
|
|
2477
|
+
<!-- measurement counts. The list tracks the dispatched -->
|
|
2478
|
+
<!-- character/text elements, less the wrappers (which recurse -->
|
|
2479
|
+
<!-- to their content), plus the logos and "url". -->
|
|
2480
|
+
<xsl:template match="pretext|latex|tex|xetex|xelatex|webwork[not(* or @copy or @source)]|today|timeofday|ad|am|bc|ca|eg|etal|etc|ie|nb|pm|ps|vs|viz|url|dataurl|icon|kbd[@name]|tag|tage|attr|pi:localize|ndash|mdash|nbsp|lsq|rsq|lq|rq|ldblbracket|rdblbracket|langle|rangle|ellipsis|midpoint|swungdash|permille|pilcrow|section-mark|minus|times|solidus|obelus|plusminus|copyright|phonomark|copyleft|registered|trademark|servicemark|degree|prime|dblprime" mode="width-text">
|
|
2481
|
+
<xsl:apply-templates select="."/>
|
|
2482
|
+
</xsl:template>
|
|
2483
|
+
|
|
2484
|
+
<!-- A fill-in blank renders as a rule or box of no characters, -->
|
|
2485
|
+
<!-- so it would measure as empty; count its "@characters" width -->
|
|
2486
|
+
<!-- (ten by default, matching the blank's own default length). -->
|
|
2487
|
+
<xsl:template match="fillin" mode="width-text">
|
|
2488
|
+
<xsl:variable name="characters">
|
|
2489
|
+
<xsl:choose>
|
|
2490
|
+
<xsl:when test="@characters">
|
|
2491
|
+
<xsl:value-of select="@characters"/>
|
|
2492
|
+
</xsl:when>
|
|
2493
|
+
<xsl:otherwise>
|
|
2494
|
+
<xsl:text>10</xsl:text>
|
|
2495
|
+
</xsl:otherwise>
|
|
2496
|
+
</xsl:choose>
|
|
2497
|
+
</xsl:variable>
|
|
2498
|
+
<xsl:value-of select="str:padding(number($characters), '0')"/>
|
|
2499
|
+
</xsl:template>
|
|
2500
|
+
|
|
2501
|
+
<xsl:template name="equal-table-columns">
|
|
2502
|
+
<xsl:param name="remaining"/>
|
|
2503
|
+
<xsl:if test="$remaining > 0">
|
|
2504
|
+
<fo:table-column column-width="proportional-column-width(1)"/>
|
|
2505
|
+
<xsl:call-template name="equal-table-columns">
|
|
2506
|
+
<xsl:with-param name="remaining" select="$remaining - 1"/>
|
|
2507
|
+
</xsl:call-template>
|
|
2508
|
+
</xsl:if>
|
|
2509
|
+
</xsl:template>
|
|
2510
|
+
|
|
2511
|
+
<!-- "tabular" mode "column-count" is shared, in pretext-common.xsl -->
|
|
2512
|
+
|
|
2513
|
+
<xsl:template match="tabular/row">
|
|
2514
|
+
<fo:table-row>
|
|
2515
|
+
<xsl:apply-templates select="cell"/>
|
|
2516
|
+
<!-- A row narrower than its table makes the tagged-table -->
|
|
2517
|
+
<!-- structure tree irregular, failing PDF/UA-1 validation -->
|
|
2518
|
+
<!-- (ISO 14289-1, via ISO 32000-1 Table 337); pad to width. -->
|
|
2519
|
+
<xsl:variable name="table-width">
|
|
2520
|
+
<xsl:apply-templates select="parent::tabular" mode="column-count"/>
|
|
2521
|
+
</xsl:variable>
|
|
2522
|
+
<xsl:call-template name="empty-table-cells">
|
|
2523
|
+
<xsl:with-param name="remaining" select="$table-width - (count(cell[not(@colspan)]) + sum(cell/@colspan))"/>
|
|
2524
|
+
</xsl:call-template>
|
|
2525
|
+
</fo:table-row>
|
|
2526
|
+
</xsl:template>
|
|
2527
|
+
|
|
2528
|
+
<xsl:template name="empty-table-cells">
|
|
2529
|
+
<xsl:param name="remaining"/>
|
|
2530
|
+
<xsl:if test="$remaining > 0">
|
|
2531
|
+
<fo:table-cell padding="2pt" start-indent="0pt" end-indent="0pt">
|
|
2532
|
+
<fo:block/>
|
|
2533
|
+
</fo:table-cell>
|
|
2534
|
+
<xsl:call-template name="empty-table-cells">
|
|
2535
|
+
<xsl:with-param name="remaining" select="$remaining - 1"/>
|
|
2536
|
+
</xsl:call-template>
|
|
2537
|
+
</xsl:if>
|
|
2538
|
+
</xsl:template>
|
|
2539
|
+
|
|
2540
|
+
<!-- A header row is bold, a visual echo of its structural role. -->
|
|
2541
|
+
<xsl:template match="row/cell">
|
|
2542
|
+
<!-- start-indent and end-indent are inherited; a centered table -->
|
|
2543
|
+
<!-- sets them on the fo:table, so reset them here or FOP shifts -->
|
|
2544
|
+
<!-- and narrows the cell content by the table's indent. -->
|
|
2545
|
+
<fo:table-cell padding="2pt" start-indent="0pt" end-indent="0pt">
|
|
2546
|
+
<xsl:if test="@colspan">
|
|
2547
|
+
<xsl:attribute name="number-columns-spanned">
|
|
2548
|
+
<xsl:value-of select="@colspan"/>
|
|
2549
|
+
</xsl:attribute>
|
|
2550
|
+
</xsl:if>
|
|
2551
|
+
<!-- vertical alignment, effective value resolved in -common -->
|
|
2552
|
+
<xsl:variable name="valign">
|
|
2553
|
+
<xsl:apply-templates select="." mode="effective-valign"/>
|
|
2554
|
+
</xsl:variable>
|
|
2555
|
+
<xsl:attribute name="display-align">
|
|
2556
|
+
<xsl:choose>
|
|
2557
|
+
<xsl:when test="$valign = 'middle'">
|
|
2558
|
+
<xsl:text>center</xsl:text>
|
|
2559
|
+
</xsl:when>
|
|
2560
|
+
<xsl:when test="$valign = 'bottom'">
|
|
2561
|
+
<xsl:text>after</xsl:text>
|
|
2562
|
+
</xsl:when>
|
|
2563
|
+
<xsl:otherwise>
|
|
2564
|
+
<xsl:text>before</xsl:text>
|
|
2565
|
+
</xsl:otherwise>
|
|
2566
|
+
</xsl:choose>
|
|
2567
|
+
</xsl:attribute>
|
|
2568
|
+
<!-- Effective rule weight per edge, resolved in -common; a -->
|
|
2569
|
+
<!-- "none" yields no border. Each cell now draws its own four -->
|
|
2570
|
+
<!-- rules, so interior rules and the whole-tabular fall-through -->
|
|
2571
|
+
<!-- appear (matching HTML and LaTeX) rather than only an outer -->
|
|
2572
|
+
<!-- frame. "effective-left"/"effective-top" return "none" away -->
|
|
2573
|
+
<!-- from the leading cell / first row, so no guard is needed. -->
|
|
2574
|
+
<xsl:call-template name="rule-attribute">
|
|
2575
|
+
<xsl:with-param name="side" select="'bottom'"/>
|
|
2576
|
+
<xsl:with-param name="thickness">
|
|
2577
|
+
<xsl:apply-templates select="." mode="effective-bottom"/>
|
|
2578
|
+
</xsl:with-param>
|
|
2579
|
+
</xsl:call-template>
|
|
2580
|
+
<xsl:call-template name="rule-attribute">
|
|
2581
|
+
<xsl:with-param name="side" select="'right'"/>
|
|
2582
|
+
<xsl:with-param name="thickness">
|
|
2583
|
+
<xsl:apply-templates select="." mode="effective-right"/>
|
|
2584
|
+
</xsl:with-param>
|
|
2585
|
+
</xsl:call-template>
|
|
2586
|
+
<xsl:call-template name="rule-attribute">
|
|
2587
|
+
<xsl:with-param name="side" select="'left'"/>
|
|
2588
|
+
<xsl:with-param name="thickness">
|
|
2589
|
+
<xsl:apply-templates select="." mode="effective-left"/>
|
|
2590
|
+
</xsl:with-param>
|
|
2591
|
+
</xsl:call-template>
|
|
2592
|
+
<xsl:call-template name="rule-attribute">
|
|
2593
|
+
<xsl:with-param name="side" select="'top'"/>
|
|
2594
|
+
<xsl:with-param name="thickness">
|
|
2595
|
+
<xsl:apply-templates select="." mode="effective-top"/>
|
|
2596
|
+
</xsl:with-param>
|
|
2597
|
+
</xsl:call-template>
|
|
2598
|
+
<xsl:variable name="the-block">
|
|
2599
|
+
<fo:block>
|
|
2600
|
+
<xsl:attribute name="text-align">
|
|
2601
|
+
<xsl:apply-templates select="." mode="effective-halign"/>
|
|
2602
|
+
</xsl:attribute>
|
|
2603
|
+
<!-- headers are bold: a header row (horizontal or -->
|
|
2604
|
+
<!-- vertical), or the leading cell of each row -->
|
|
2605
|
+
<!-- when the tabular requests row headers -->
|
|
2606
|
+
<xsl:if test="(parent::row/@header = 'yes') or (parent::row/@header = 'vertical') or ((ancestor::tabular/@row-headers = 'yes') and not(preceding-sibling::cell))">
|
|
2607
|
+
<xsl:attribute name="font-weight">
|
|
2608
|
+
<xsl:text>bold</xsl:text>
|
|
2609
|
+
</xsl:attribute>
|
|
2610
|
+
</xsl:if>
|
|
2611
|
+
<xsl:choose>
|
|
2612
|
+
<!-- structured: paragraphs or lines as blocks -->
|
|
2613
|
+
<xsl:when test="p|line">
|
|
2614
|
+
<xsl:apply-templates select="*"/>
|
|
2615
|
+
</xsl:when>
|
|
2616
|
+
<!-- mixed content, right here -->
|
|
2617
|
+
<xsl:otherwise>
|
|
2618
|
+
<xsl:apply-templates/>
|
|
2619
|
+
</xsl:otherwise>
|
|
2620
|
+
</xsl:choose>
|
|
2621
|
+
</fo:block>
|
|
2622
|
+
</xsl:variable>
|
|
2623
|
+
<xsl:choose>
|
|
2624
|
+
<!-- A vertical header rotates a quarter-turn, reading -->
|
|
2625
|
+
<!-- bottom-up. FOP wants the extent of the rotated text -->
|
|
2626
|
+
<!-- declared, so the longest text (or "line") among the -->
|
|
2627
|
+
<!-- row's cells estimates a common height for the row. -->
|
|
2628
|
+
<xsl:when test="parent::row/@header = 'vertical'">
|
|
2629
|
+
<xsl:variable name="longest-text">
|
|
2630
|
+
<xsl:for-each select="parent::row/cell/line|parent::row/cell[not(line)]">
|
|
2631
|
+
<xsl:sort select="string-length(normalize-space(.))" data-type="number" order="descending"/>
|
|
2632
|
+
<xsl:if test="position() = 1">
|
|
2633
|
+
<xsl:value-of select="string-length(normalize-space(.))"/>
|
|
2634
|
+
</xsl:if>
|
|
2635
|
+
</xsl:for-each>
|
|
2636
|
+
</xsl:variable>
|
|
2637
|
+
<fo:block-container reference-orientation="90"
|
|
2638
|
+
inline-progression-dimension="{format-number(0.5 * $longest-text + 1.5, '0.#')}em">
|
|
2639
|
+
<xsl:copy-of select="$the-block"/>
|
|
2640
|
+
</fo:block-container>
|
|
2641
|
+
</xsl:when>
|
|
2642
|
+
<xsl:otherwise>
|
|
2643
|
+
<xsl:copy-of select="$the-block"/>
|
|
2644
|
+
</xsl:otherwise>
|
|
2645
|
+
</xsl:choose>
|
|
2646
|
+
</fo:table-cell>
|
|
2647
|
+
</xsl:template>
|
|
2648
|
+
|
|
2649
|
+
<!-- The schema's rule thicknesses, emitted as a border on the -->
|
|
2650
|
+
<!-- given side; "none", or no specification, means no border. -->
|
|
2651
|
+
<xsl:template name="rule-attribute">
|
|
2652
|
+
<xsl:param name="side"/>
|
|
2653
|
+
<xsl:param name="thickness"/>
|
|
2654
|
+
<xsl:variable name="width">
|
|
2655
|
+
<xsl:choose>
|
|
2656
|
+
<xsl:when test="$thickness = 'minor'">
|
|
2657
|
+
<xsl:text>0.5pt</xsl:text>
|
|
2658
|
+
</xsl:when>
|
|
2659
|
+
<xsl:when test="$thickness = 'medium'">
|
|
2660
|
+
<xsl:text>1pt</xsl:text>
|
|
2661
|
+
</xsl:when>
|
|
2662
|
+
<xsl:when test="$thickness = 'major'">
|
|
2663
|
+
<xsl:text>2pt</xsl:text>
|
|
2664
|
+
</xsl:when>
|
|
2665
|
+
<xsl:otherwise/>
|
|
2666
|
+
</xsl:choose>
|
|
2667
|
+
</xsl:variable>
|
|
2668
|
+
<xsl:if test="not($width = '')">
|
|
2669
|
+
<xsl:attribute name="border-{$side}">
|
|
2670
|
+
<xsl:text>solid </xsl:text>
|
|
2671
|
+
<xsl:value-of select="$width"/>
|
|
2672
|
+
<xsl:text> #000000</xsl:text>
|
|
2673
|
+
</xsl:attribute>
|
|
2674
|
+
</xsl:if>
|
|
2675
|
+
</xsl:template>
|
|
2676
|
+
|
|
2677
|
+
<!-- A "line" is one line of several, in a cell, an address, an -->
|
|
2678
|
+
<!-- attribution: its own block, alignment from the surroundings. -->
|
|
2679
|
+
<xsl:template match="line">
|
|
2680
|
+
<fo:block>
|
|
2681
|
+
<xsl:apply-templates/>
|
|
2682
|
+
</fo:block>
|
|
2683
|
+
</xsl:template>
|
|
2684
|
+
|
|
2685
|
+
<!-- ############ -->
|
|
2686
|
+
<!-- Bibliography -->
|
|
2687
|
+
<!-- ############ -->
|
|
2688
|
+
|
|
2689
|
+
<!-- pretext-common.xsl implements "biblio" entries (raw, BibTeX, -->
|
|
2690
|
+
<!-- and CSL flavors) and the typography of their fields, via the -->
|
|
2691
|
+
<!-- abstract font modes implemented in "Inline Markup". Here: -->
|
|
2692
|
+
<!-- the entry wrapper and a hanging "[N]" label. A biblio's -->
|
|
2693
|
+
<!-- "title", "author", etc. are killed elsewhere as metadata, so -->
|
|
2694
|
+
<!-- this template overrides those kills to route the fields to -->
|
|
2695
|
+
<!-- common's typography; a field common does not style falls -->
|
|
2696
|
+
<!-- through to its text, which is right for raw mixed content. -->
|
|
2697
|
+
<xsl:template match="biblio|biblio/*">
|
|
2698
|
+
<xsl:apply-imports/>
|
|
2699
|
+
</xsl:template>
|
|
2700
|
+
|
|
2701
|
+
<!-- A "note" of a bibliography entry is annotation prose, and an -->
|
|
2702
|
+
<!-- "xref" target. -->
|
|
2703
|
+
<xsl:template match="biblio/note">
|
|
2704
|
+
<fo:inline>
|
|
2705
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
2706
|
+
<xsl:text> </xsl:text>
|
|
2707
|
+
<xsl:apply-templates/>
|
|
2708
|
+
</fo:inline>
|
|
2709
|
+
</xsl:template>
|
|
2710
|
+
|
|
2711
|
+
<!-- pretext-common.xsl kills "author" and "editor" globally, as -->
|
|
2712
|
+
<!-- metadata, and styles them only in a BibTeX-flavored entry; -->
|
|
2713
|
+
<!-- in a raw entry they are authored display text, passing -->
|
|
2714
|
+
<!-- through (and so shadowing the kill reached by the -->
|
|
2715
|
+
<!-- apply-imports above). -->
|
|
2716
|
+
<xsl:template match="biblio[@type = 'raw']/author|biblio[@type = 'raw']/editor">
|
|
2717
|
+
<xsl:apply-templates/>
|
|
2718
|
+
</xsl:template>
|
|
2719
|
+
|
|
2720
|
+
<!-- Render the parts of a CSL "name"; the catch-all "*" harness -->
|
|
2721
|
+
<!-- below drops their text, but only until it is removed. -->
|
|
2722
|
+
<xsl:template match="biblio/author/name/* | biblio/editor/name/* | biblio/translator/name/*">
|
|
2723
|
+
<xsl:apply-templates/>
|
|
2724
|
+
</xsl:template>
|
|
2725
|
+
|
|
2726
|
+
<xsl:template match="biblio" mode="bibentry-wrapper">
|
|
2727
|
+
<xsl:param name="content"/>
|
|
2728
|
+
<fo:list-block provisional-distance-between-starts="2.5em"
|
|
2729
|
+
provisional-label-separation="0.5em"
|
|
2730
|
+
space-after="0.5em">
|
|
2731
|
+
<fo:list-item>
|
|
2732
|
+
<fo:list-item-label end-indent="label-end()">
|
|
2733
|
+
<fo:block text-align="end">
|
|
2734
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
2735
|
+
<xsl:text>[</xsl:text>
|
|
2736
|
+
<xsl:apply-templates select="." mode="serial-number"/>
|
|
2737
|
+
<xsl:text>]</xsl:text>
|
|
2738
|
+
</fo:block>
|
|
2739
|
+
</fo:list-item-label>
|
|
2740
|
+
<fo:list-item-body start-indent="body-start()">
|
|
2741
|
+
<fo:block text-align="{$text-alignment}">
|
|
2742
|
+
<xsl:copy-of select="$content"/>
|
|
2743
|
+
</fo:block>
|
|
2744
|
+
</fo:list-item-body>
|
|
2745
|
+
</fo:list-item>
|
|
2746
|
+
</fo:list-block>
|
|
2747
|
+
</xsl:template>
|
|
2748
|
+
|
|
2749
|
+
<!-- the period finishing a structured entry -->
|
|
2750
|
+
<xsl:template name="biblio-period">
|
|
2751
|
+
<xsl:text>.</xsl:text>
|
|
2752
|
+
</xsl:template>
|
|
2753
|
+
|
|
2754
|
+
<!-- ###### -->
|
|
2755
|
+
<!-- Units -->
|
|
2756
|
+
<!-- ###### -->
|
|
2757
|
+
|
|
2758
|
+
<!-- A "quantity" is a magnitude and/or units, in the manner of -->
|
|
2759
|
+
<!-- the LaTeX "siunitx" package: prefixes and bases become their -->
|
|
2760
|
+
<!-- abbreviations (the lookup tables of pretext-units.xsl), with -->
|
|
2761
|
+
<!-- superscript exponents, and a solidus before "per" units. -->
|
|
2762
|
+
<xsl:key name="prefix-key" match="prefix" use="concat(../@name, @full)"/>
|
|
2763
|
+
<xsl:key name="base-key" match="base" use="concat(../@name, @full)"/>
|
|
2764
|
+
|
|
2765
|
+
<xsl:template match="quantity">
|
|
2766
|
+
<xsl:apply-templates select="mag"/>
|
|
2767
|
+
<xsl:if test="mag and (unit or per)">
|
|
2768
|
+
<!-- a thin space, as siunitx -->
|
|
2769
|
+
<xsl:text> </xsl:text>
|
|
2770
|
+
</xsl:if>
|
|
2771
|
+
<xsl:if test="not(unit) and per">
|
|
2772
|
+
<xsl:text>1</xsl:text>
|
|
2773
|
+
</xsl:if>
|
|
2774
|
+
<xsl:apply-templates select="unit"/>
|
|
2775
|
+
<xsl:if test="per">
|
|
2776
|
+
<xsl:text>/</xsl:text>
|
|
2777
|
+
<xsl:apply-templates select="per"/>
|
|
2778
|
+
</xsl:if>
|
|
2779
|
+
</xsl:template>
|
|
2780
|
+
|
|
2781
|
+
<!-- magnitudes are typically numbers; authored LaTeX macros -->
|
|
2782
|
+
<!-- (e.g. "\pi") will await the math machinery -->
|
|
2783
|
+
<xsl:template match="quantity/mag">
|
|
2784
|
+
<xsl:value-of select="."/>
|
|
2785
|
+
</xsl:template>
|
|
2786
|
+
|
|
2787
|
+
<xsl:template match="quantity/unit|quantity/per">
|
|
2788
|
+
<!-- multiple units separated by a thin space -->
|
|
2789
|
+
<xsl:if test="(self::unit and preceding-sibling::unit) or (self::per and preceding-sibling::per)">
|
|
2790
|
+
<xsl:text> </xsl:text>
|
|
2791
|
+
</xsl:if>
|
|
2792
|
+
<xsl:variable name="the-prefix" select="@prefix"/>
|
|
2793
|
+
<xsl:if test="@prefix">
|
|
2794
|
+
<xsl:for-each select="document('pretext-units.xsl')">
|
|
2795
|
+
<xsl:value-of select="key('prefix-key', concat('prefixes', $the-prefix))/@short"/>
|
|
2796
|
+
</xsl:for-each>
|
|
2797
|
+
</xsl:if>
|
|
2798
|
+
<xsl:variable name="the-base" select="@base"/>
|
|
2799
|
+
<xsl:for-each select="document('pretext-units.xsl')">
|
|
2800
|
+
<xsl:value-of select="key('base-key', concat('bases', $the-base))/@short"/>
|
|
2801
|
+
</xsl:for-each>
|
|
2802
|
+
<xsl:if test="@exp">
|
|
2803
|
+
<!-- a raised exponent, shifted a fixed fraction of the line-height -->
|
|
2804
|
+
<fo:inline baseline-shift="35%" font-size="70%">
|
|
2805
|
+
<xsl:value-of select="@exp"/>
|
|
2806
|
+
</fo:inline>
|
|
2807
|
+
</xsl:if>
|
|
2808
|
+
</xsl:template>
|
|
2809
|
+
|
|
2810
|
+
<!-- ################ -->
|
|
2811
|
+
<!-- Quoted and Lined -->
|
|
2812
|
+
<!-- ################ -->
|
|
2813
|
+
|
|
2814
|
+
<!-- A "blockquote" indents on both sides; any "attribution" -->
|
|
2815
|
+
<!-- finishes it, right-aligned, introduced by an em-dash. -->
|
|
2816
|
+
<xsl:template match="blockquote">
|
|
2817
|
+
<fo:block margin-left="2.5em" margin-right="2.5em" space-before="0.75em" space-after="0.75em">
|
|
2818
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
2819
|
+
<xsl:apply-templates select="*"/>
|
|
2820
|
+
</fo:block>
|
|
2821
|
+
</xsl:template>
|
|
2822
|
+
|
|
2823
|
+
<xsl:template match="attribution">
|
|
2824
|
+
<xsl:choose>
|
|
2825
|
+
<!-- several "line"s: each right-aligned, the dash leading the -->
|
|
2826
|
+
<!-- first, since a bare "line" is its own block and would strand -->
|
|
2827
|
+
<!-- the dash on a line of its own -->
|
|
2828
|
+
<xsl:when test="line">
|
|
2829
|
+
<xsl:for-each select="line">
|
|
2830
|
+
<fo:block text-align="end">
|
|
2831
|
+
<xsl:if test="position() = 1">
|
|
2832
|
+
<xsl:call-template name="mdash-character"/>
|
|
2833
|
+
</xsl:if>
|
|
2834
|
+
<xsl:apply-templates/>
|
|
2835
|
+
</fo:block>
|
|
2836
|
+
</xsl:for-each>
|
|
2837
|
+
</xsl:when>
|
|
2838
|
+
<xsl:otherwise>
|
|
2839
|
+
<fo:block text-align="end">
|
|
2840
|
+
<xsl:call-template name="mdash-character"/>
|
|
2841
|
+
<xsl:apply-templates/>
|
|
2842
|
+
</fo:block>
|
|
2843
|
+
</xsl:otherwise>
|
|
2844
|
+
</xsl:choose>
|
|
2845
|
+
</xsl:template>
|
|
2846
|
+
|
|
2847
|
+
<!-- A "poem": title centered, stanzas of lines, a flush-left -->
|
|
2848
|
+
<!-- author. Fancy authored alignment/indentation of individual -->
|
|
2849
|
+
<!-- lines is a refinement for later. -->
|
|
2850
|
+
<xsl:template match="poem">
|
|
2851
|
+
<fo:block margin-left="2.5em" margin-right="2.5em" space-before="0.75em" space-after="0.75em">
|
|
2852
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
2853
|
+
<xsl:if test="title">
|
|
2854
|
+
<fo:block font-weight="bold" text-align="center" space-after="0.5em">
|
|
2855
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
2856
|
+
</fo:block>
|
|
2857
|
+
</xsl:if>
|
|
2858
|
+
<xsl:apply-templates select="idx"/>
|
|
2859
|
+
<xsl:apply-templates select="stanza|line"/>
|
|
2860
|
+
<xsl:apply-templates select="author" mode="poem-author"/>
|
|
2861
|
+
</fo:block>
|
|
2862
|
+
</xsl:template>
|
|
2863
|
+
|
|
2864
|
+
<xsl:template match="stanza">
|
|
2865
|
+
<fo:block space-after="0.75em">
|
|
2866
|
+
<xsl:apply-templates select="idx"/>
|
|
2867
|
+
<xsl:apply-templates select="line"/>
|
|
2868
|
+
</fo:block>
|
|
2869
|
+
</xsl:template>
|
|
2870
|
+
|
|
2871
|
+
<!-- "author" is metadata, killed in the default mode by -->
|
|
2872
|
+
<!-- pretext-common.xsl, so a modal template places it -->
|
|
2873
|
+
<xsl:template match="poem/author" mode="poem-author">
|
|
2874
|
+
<fo:block text-align="start" font-style="italic">
|
|
2875
|
+
<xsl:apply-templates/>
|
|
2876
|
+
</fo:block>
|
|
2877
|
+
</xsl:template>
|
|
2878
|
+
|
|
2879
|
+
<!-- A "fillin" blank, sized by @characters (ten if unspecified), -->
|
|
2880
|
+
<!-- in the publisher's chosen text style: an underline rule (the -->
|
|
2881
|
+
<!-- default), an empty outlined box, or a shaded box. Fill-ins -->
|
|
2882
|
+
<!-- inside mathematics travel with the LaTeX, where MathJax -->
|
|
2883
|
+
<!-- renders them in the publisher's math style. -->
|
|
2884
|
+
<xsl:template match="fillin[not(parent::m or parent::mrow)]">
|
|
2885
|
+
<xsl:variable name="blank-length">
|
|
2886
|
+
<xsl:choose>
|
|
2887
|
+
<xsl:when test="@characters">
|
|
2888
|
+
<xsl:value-of select="format-number(0.55 * @characters, '0.##')"/>
|
|
2889
|
+
</xsl:when>
|
|
2890
|
+
<xsl:otherwise>
|
|
2891
|
+
<xsl:value-of select="format-number(0.55 * 10, '0.##')"/>
|
|
2892
|
+
</xsl:otherwise>
|
|
2893
|
+
</xsl:choose>
|
|
2894
|
+
<xsl:text>em</xsl:text>
|
|
2895
|
+
</xsl:variable>
|
|
2896
|
+
<xsl:choose>
|
|
2897
|
+
<xsl:when test="$fillin-text-style = 'box'">
|
|
2898
|
+
<fo:inline border-style="solid" border-width="0.5pt">
|
|
2899
|
+
<fo:leader leader-pattern="space" leader-length="{$blank-length}"/>
|
|
2900
|
+
</fo:inline>
|
|
2901
|
+
</xsl:when>
|
|
2902
|
+
<xsl:when test="$fillin-text-style = 'shade'">
|
|
2903
|
+
<fo:inline background-color="#D9D9D9">
|
|
2904
|
+
<fo:leader leader-pattern="space" leader-length="{$blank-length}"/>
|
|
2905
|
+
</fo:inline>
|
|
2906
|
+
</xsl:when>
|
|
2907
|
+
<!-- "underline", the default -->
|
|
2908
|
+
<xsl:otherwise>
|
|
2909
|
+
<fo:leader leader-pattern="rule"
|
|
2910
|
+
rule-thickness="0.5pt"
|
|
2911
|
+
rule-style="solid"
|
|
2912
|
+
leader-length="{$blank-length}"/>
|
|
2913
|
+
</xsl:otherwise>
|
|
2914
|
+
</xsl:choose>
|
|
2915
|
+
</xsl:template>
|
|
2916
|
+
|
|
2917
|
+
<!-- ######## -->
|
|
2918
|
+
<!-- Verbatim -->
|
|
2919
|
+
<!-- ######## -->
|
|
2920
|
+
|
|
2921
|
+
<!-- The workhorse: one block of literal text in a monospace font, -->
|
|
2922
|
+
<!-- slightly reduced, with every space and linefeed preserved, and -->
|
|
2923
|
+
<!-- no line-wrapping. Optionally boxed (e.g. Sage input). -->
|
|
2924
|
+
<xsl:template name="verbatim-block">
|
|
2925
|
+
<xsl:param name="content"/>
|
|
2926
|
+
<xsl:param name="boxed" select="false()"/>
|
|
2927
|
+
<!-- a "cd" interrupting a paragraph must not inherit its first-line indent -->
|
|
2928
|
+
<fo:block font-family="{$font-family-monospace}"
|
|
2929
|
+
font-size="90%"
|
|
2930
|
+
white-space-collapse="false"
|
|
2931
|
+
white-space-treatment="preserve"
|
|
2932
|
+
linefeed-treatment="preserve"
|
|
2933
|
+
wrap-option="no-wrap"
|
|
2934
|
+
text-align="start"
|
|
2935
|
+
text-indent="0"
|
|
2936
|
+
space-before="0.5em"
|
|
2937
|
+
space-after="0.5em">
|
|
2938
|
+
<xsl:if test="$boxed">
|
|
2939
|
+
<xsl:attribute name="border">
|
|
2940
|
+
<xsl:text>solid 0.5pt #888888</xsl:text>
|
|
2941
|
+
</xsl:attribute>
|
|
2942
|
+
<xsl:attribute name="padding">
|
|
2943
|
+
<xsl:text>3pt</xsl:text>
|
|
2944
|
+
</xsl:attribute>
|
|
2945
|
+
<!-- the shared Sage-input tint, defined in pretext-common.xsl -->
|
|
2946
|
+
<xsl:attribute name="background-color">
|
|
2947
|
+
<xsl:text>#</xsl:text>
|
|
2948
|
+
<xsl:value-of select="$sage-input-background"/>
|
|
2949
|
+
</xsl:attribute>
|
|
2950
|
+
<!-- FO draws a block's border and padding outward from -->
|
|
2951
|
+
<!-- the content edge; indenting the content by border + -->
|
|
2952
|
+
<!-- padding (3.5pt) keeps the box flush with the margins.-->
|
|
2953
|
+
<xsl:attribute name="start-indent">
|
|
2954
|
+
<xsl:text>3.5pt</xsl:text>
|
|
2955
|
+
</xsl:attribute>
|
|
2956
|
+
<xsl:attribute name="end-indent">
|
|
2957
|
+
<xsl:text>3.5pt</xsl:text>
|
|
2958
|
+
</xsl:attribute>
|
|
2959
|
+
</xsl:if>
|
|
2960
|
+
<xsl:copy-of select="$content"/>
|
|
2961
|
+
</fo:block>
|
|
2962
|
+
</xsl:template>
|
|
2963
|
+
|
|
2964
|
+
<!-- "pre" is the pure display of literal text; the "interior" -->
|
|
2965
|
+
<!-- machinery of pretext-common.xsl scrubs the indentation, -->
|
|
2966
|
+
<!-- handling text or "cline" structure alike. -->
|
|
2967
|
+
<xsl:template match="pre">
|
|
2968
|
+
<xsl:call-template name="verbatim-block">
|
|
2969
|
+
<xsl:with-param name="content">
|
|
2970
|
+
<xsl:apply-templates select="." mode="interior"/>
|
|
2971
|
+
</xsl:with-param>
|
|
2972
|
+
</xsl:call-template>
|
|
2973
|
+
</xsl:template>
|
|
2974
|
+
|
|
2975
|
+
<!-- A "cd" (code display) interrupts a paragraph with a short -->
|
|
2976
|
+
<!-- hunk of verbatim text, either mixed content or "cline"s. -->
|
|
2977
|
+
<!-- With @showspaces="all" every space becomes a visible OPEN -->
|
|
2978
|
+
<!-- BOX, as in the HTML conversion (the monospace font carries -->
|
|
2979
|
+
<!-- the glyph); the "cline" flavor is handled in a variant below. -->
|
|
2980
|
+
<xsl:template match="cd">
|
|
2981
|
+
<xsl:call-template name="verbatim-block">
|
|
2982
|
+
<xsl:with-param name="content">
|
|
2983
|
+
<xsl:choose>
|
|
2984
|
+
<xsl:when test="cline">
|
|
2985
|
+
<xsl:apply-templates select="cline"/>
|
|
2986
|
+
</xsl:when>
|
|
2987
|
+
<xsl:when test="@showspaces = 'all'">
|
|
2988
|
+
<xsl:value-of select="str:replace(., ' ', '␣')"/>
|
|
2989
|
+
</xsl:when>
|
|
2990
|
+
<xsl:otherwise>
|
|
2991
|
+
<xsl:value-of select="."/>
|
|
2992
|
+
</xsl:otherwise>
|
|
2993
|
+
</xsl:choose>
|
|
2994
|
+
</xsl:with-param>
|
|
2995
|
+
</xsl:call-template>
|
|
2996
|
+
</xsl:template>
|
|
2997
|
+
|
|
2998
|
+
<!-- A "cline" of a "cd" with visible spaces, as in the HTML -->
|
|
2999
|
+
<!-- conversion: each space becomes the OPEN BOX glyph. -->
|
|
3000
|
+
<xsl:template match="cline[parent::cd/@showspaces = 'all']">
|
|
3001
|
+
<xsl:value-of select="str:replace(., ' ', '␣')"/>
|
|
3002
|
+
<xsl:text>
</xsl:text>
|
|
3003
|
+
</xsl:template>
|
|
3004
|
+
|
|
3005
|
+
<!-- A "program" renders its visible source code; line numbers, -->
|
|
3006
|
+
<!-- line highlighting, and visible preambles/postambles are -->
|
|
3007
|
+
<!-- refinements for later. -->
|
|
3008
|
+
<xsl:template match="program">
|
|
3009
|
+
<xsl:call-template name="verbatim-block">
|
|
3010
|
+
<xsl:with-param name="content">
|
|
3011
|
+
<xsl:call-template name="sanitize-text">
|
|
3012
|
+
<xsl:with-param name="text">
|
|
3013
|
+
<xsl:choose>
|
|
3014
|
+
<xsl:when test="code">
|
|
3015
|
+
<xsl:value-of select="code"/>
|
|
3016
|
+
</xsl:when>
|
|
3017
|
+
<xsl:otherwise>
|
|
3018
|
+
<xsl:value-of select="."/>
|
|
3019
|
+
</xsl:otherwise>
|
|
3020
|
+
</xsl:choose>
|
|
3021
|
+
</xsl:with-param>
|
|
3022
|
+
</xsl:call-template>
|
|
3023
|
+
</xsl:with-param>
|
|
3024
|
+
</xsl:call-template>
|
|
3025
|
+
</xsl:template>
|
|
3026
|
+
|
|
3027
|
+
<!-- A "console" session: each "input" line carries its prompt -->
|
|
3028
|
+
<!-- (resolved by pretext-common.xsl) and is bold, distinct from -->
|
|
3029
|
+
<!-- plain "output". Continuation lines are a refinement. -->
|
|
3030
|
+
<xsl:template match="console">
|
|
3031
|
+
<xsl:call-template name="verbatim-block">
|
|
3032
|
+
<xsl:with-param name="content">
|
|
3033
|
+
<xsl:apply-templates select="input|output"/>
|
|
3034
|
+
</xsl:with-param>
|
|
3035
|
+
</xsl:call-template>
|
|
3036
|
+
</xsl:template>
|
|
3037
|
+
|
|
3038
|
+
<xsl:template match="console/input">
|
|
3039
|
+
<fo:inline font-weight="bold">
|
|
3040
|
+
<xsl:apply-templates select="." mode="determine-console-prompt"/>
|
|
3041
|
+
<xsl:call-template name="sanitize-text">
|
|
3042
|
+
<xsl:with-param name="text" select="."/>
|
|
3043
|
+
</xsl:call-template>
|
|
3044
|
+
</fo:inline>
|
|
3045
|
+
</xsl:template>
|
|
3046
|
+
|
|
3047
|
+
<xsl:template match="console/output">
|
|
3048
|
+
<xsl:call-template name="sanitize-text">
|
|
3049
|
+
<xsl:with-param name="text" select="."/>
|
|
3050
|
+
</xsl:call-template>
|
|
3051
|
+
</xsl:template>
|
|
3052
|
+
|
|
3053
|
+
<!-- A "sage" cell: the input boxed, any output following plain. -->
|
|
3054
|
+
<!-- An empty cell is an interactive invitation, nothing on paper. -->
|
|
3055
|
+
<xsl:template match="sage">
|
|
3056
|
+
<xsl:if test="input">
|
|
3057
|
+
<xsl:call-template name="verbatim-block">
|
|
3058
|
+
<xsl:with-param name="boxed" select="true()"/>
|
|
3059
|
+
<xsl:with-param name="content">
|
|
3060
|
+
<xsl:call-template name="sanitize-text">
|
|
3061
|
+
<xsl:with-param name="text" select="input"/>
|
|
3062
|
+
</xsl:call-template>
|
|
3063
|
+
</xsl:with-param>
|
|
3064
|
+
</xsl:call-template>
|
|
3065
|
+
</xsl:if>
|
|
3066
|
+
<xsl:if test="output">
|
|
3067
|
+
<xsl:call-template name="verbatim-block">
|
|
3068
|
+
<xsl:with-param name="content">
|
|
3069
|
+
<xsl:call-template name="sanitize-text">
|
|
3070
|
+
<xsl:with-param name="text" select="output"/>
|
|
3071
|
+
</xsl:call-template>
|
|
3072
|
+
</xsl:with-param>
|
|
3073
|
+
</xsl:call-template>
|
|
3074
|
+
</xsl:if>
|
|
3075
|
+
</xsl:template>
|
|
3076
|
+
|
|
3077
|
+
<!-- ############ -->
|
|
3078
|
+
<!-- Side-by-Side -->
|
|
3079
|
+
<!-- ############ -->
|
|
3080
|
+
|
|
3081
|
+
<!-- A "sidebyside" lays out its panels horizontally, as an -->
|
|
3082
|
+
<!-- fo:table with a single row. pretext-common.xsl computes the -->
|
|
3083
|
+
<!-- whole layout from the authored attributes: per-panel widths -->
|
|
3084
|
+
<!-- and vertical alignments, outer margins, and the uniform space -->
|
|
3085
|
+
<!-- between panels. Margins and inter-panel spaces become empty -->
|
|
3086
|
+
<!-- columns. The panel element list mirrors the one in the -->
|
|
3087
|
+
<!-- "sidebyside" main template of pretext-common.xsl. -->
|
|
3088
|
+
<xsl:template match="sidebyside">
|
|
3089
|
+
<xsl:apply-templates select="." mode="forced-pagebreak"/>
|
|
3090
|
+
<xsl:variable name="panels" select="p|pre|ol|ul|dl|program|console|poem|audio|video|interactive|slate|exercise|image|figure|table|listing|list|tabular|stack|jsxgraph|paragraphs"/>
|
|
3091
|
+
<xsl:variable name="rtf-layout">
|
|
3092
|
+
<xsl:apply-templates select="." mode="layout-parameters"/>
|
|
3093
|
+
</xsl:variable>
|
|
3094
|
+
<xsl:variable name="layout" select="exsl:node-set($rtf-layout)"/>
|
|
3095
|
+
<xsl:variable name="has-left-margin" select="number(substring-before($layout/left-margin, '%')) > 0"/>
|
|
3096
|
+
<xsl:variable name="has-right-margin" select="number(substring-before($layout/right-margin, '%')) > 0"/>
|
|
3097
|
+
<xsl:variable name="has-gaps" select="number(substring-before($layout/space-width, '%')) > 0"/>
|
|
3098
|
+
<!-- a row without cells is fatal to FOP, so no panels, no table -->
|
|
3099
|
+
<xsl:if test="$panels">
|
|
3100
|
+
<!-- Keep a "sidebyside" whole on a page when it fits, matching -->
|
|
3101
|
+
<!-- LaTeX, where its panels are an unbreakable "tcbraster". As -->
|
|
3102
|
+
<!-- for a "tabular", the finite strength lets FOP break one too -->
|
|
3103
|
+
<!-- tall for a page instead of clipping it; tune it if needed. -->
|
|
3104
|
+
<fo:table table-layout="fixed" width="100%" space-before="0.5em" space-after="0.5em" keep-together.within-page="5">
|
|
3105
|
+
<xsl:if test="$has-left-margin">
|
|
3106
|
+
<fo:table-column column-width="proportional-column-width({substring-before($layout/left-margin, '%')})"/>
|
|
3107
|
+
</xsl:if>
|
|
3108
|
+
<xsl:for-each select="$layout/width">
|
|
3109
|
+
<xsl:if test="(position() > 1) and $has-gaps">
|
|
3110
|
+
<fo:table-column column-width="proportional-column-width({substring-before($layout/space-width, '%')})"/>
|
|
3111
|
+
</xsl:if>
|
|
3112
|
+
<fo:table-column column-width="proportional-column-width({substring-before(., '%')})"/>
|
|
3113
|
+
</xsl:for-each>
|
|
3114
|
+
<xsl:if test="$has-right-margin">
|
|
3115
|
+
<fo:table-column column-width="proportional-column-width({substring-before($layout/right-margin, '%')})"/>
|
|
3116
|
+
</xsl:if>
|
|
3117
|
+
<fo:table-body>
|
|
3118
|
+
<fo:table-row>
|
|
3119
|
+
<xsl:if test="$has-left-margin">
|
|
3120
|
+
<fo:table-cell>
|
|
3121
|
+
<fo:block/>
|
|
3122
|
+
</fo:table-cell>
|
|
3123
|
+
</xsl:if>
|
|
3124
|
+
<xsl:for-each select="$panels">
|
|
3125
|
+
<xsl:variable name="panel-number" select="position()"/>
|
|
3126
|
+
<xsl:if test="($panel-number > 1) and $has-gaps">
|
|
3127
|
+
<fo:table-cell>
|
|
3128
|
+
<fo:block/>
|
|
3129
|
+
</fo:table-cell>
|
|
3130
|
+
</xsl:if>
|
|
3131
|
+
<fo:table-cell>
|
|
3132
|
+
<xsl:attribute name="display-align">
|
|
3133
|
+
<xsl:choose>
|
|
3134
|
+
<xsl:when test="$layout/valign[$panel-number] = 'middle'">
|
|
3135
|
+
<xsl:text>center</xsl:text>
|
|
3136
|
+
</xsl:when>
|
|
3137
|
+
<xsl:when test="$layout/valign[$panel-number] = 'bottom'">
|
|
3138
|
+
<xsl:text>after</xsl:text>
|
|
3139
|
+
</xsl:when>
|
|
3140
|
+
<xsl:otherwise>
|
|
3141
|
+
<xsl:text>before</xsl:text>
|
|
3142
|
+
</xsl:otherwise>
|
|
3143
|
+
</xsl:choose>
|
|
3144
|
+
</xsl:attribute>
|
|
3145
|
+
<xsl:apply-templates select="."/>
|
|
3146
|
+
</fo:table-cell>
|
|
3147
|
+
</xsl:for-each>
|
|
3148
|
+
</fo:table-row>
|
|
3149
|
+
</fo:table-body>
|
|
3150
|
+
</fo:table>
|
|
3151
|
+
</xsl:if>
|
|
3152
|
+
</xsl:template>
|
|
3153
|
+
|
|
3154
|
+
<!-- A "stack" stacks several items vertically within one panel; -->
|
|
3155
|
+
<!-- the child list again mirrors pretext-common.xsl. -->
|
|
3156
|
+
<xsl:template match="sidebyside/stack">
|
|
3157
|
+
<xsl:apply-templates select="tabular|image|p|pre|ol|ul|dl|audio|video|interactive|slate|program|console|exercise"/>
|
|
3158
|
+
</xsl:template>
|
|
3159
|
+
|
|
3160
|
+
<!-- A "sbsgroup" is as pure a container as there can be: the -->
|
|
3161
|
+
<!-- "sidebyside" children just pile up vertically. (Common -->
|
|
3162
|
+
<!-- layout attributes on the group are consulted by each -->
|
|
3163
|
+
<!-- "sidebyside" via the layout machinery.) -->
|
|
3164
|
+
<xsl:template match="sbsgroup">
|
|
3165
|
+
<xsl:apply-templates select="." mode="forced-pagebreak"/>
|
|
3166
|
+
<xsl:apply-templates select="sidebyside"/>
|
|
3167
|
+
</xsl:template>
|
|
3168
|
+
|
|
3169
|
+
<!-- ################### -->
|
|
3170
|
+
<!-- Figures and Caption -->
|
|
3171
|
+
<!-- ################### -->
|
|
3172
|
+
|
|
3173
|
+
<!-- The FIGURE-LIKE blocks (a captioned "figure"; and "table", -->
|
|
3174
|
+
<!-- "listing", "list", each titled) wrap their contents and -->
|
|
3175
|
+
<!-- finish with a caption: a body-aligned paragraph led by a -->
|
|
3176
|
+
<!-- bold run-in heading (the type name and number), so a long -->
|
|
3177
|
+
<!-- caption sets as ordinary prose, not centered ragged lines. -->
|
|
3178
|
+
<!-- All share one counter. The "caption" element is consumed -->
|
|
3179
|
+
<!-- here, so it is killed in the default mode, with the rest -->
|
|
3180
|
+
<!-- of the metadata. -->
|
|
3181
|
+
<xsl:template match="&FIGURE-LIKE;">
|
|
3182
|
+
<xsl:apply-templates select="." mode="forced-pagebreak"/>
|
|
3183
|
+
<fo:block space-before="1em" space-after="1em">
|
|
3184
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
3185
|
+
<xsl:apply-templates select="*"/>
|
|
3186
|
+
<fo:block text-align="{$text-alignment}" space-before="0.5em" keep-with-previous.within-page="always">
|
|
3187
|
+
<fo:inline font-weight="bold">
|
|
3188
|
+
<xsl:apply-templates select="." mode="type-name"/>
|
|
3189
|
+
<xsl:variable name="the-number">
|
|
3190
|
+
<xsl:apply-templates select="." mode="number"/>
|
|
3191
|
+
</xsl:variable>
|
|
3192
|
+
<xsl:if test="not($the-number = '')">
|
|
3193
|
+
<xsl:text> </xsl:text>
|
|
3194
|
+
<xsl:value-of select="$the-number"/>
|
|
3195
|
+
</xsl:if>
|
|
3196
|
+
<xsl:text>.</xsl:text>
|
|
3197
|
+
</fo:inline>
|
|
3198
|
+
<xsl:text> </xsl:text>
|
|
3199
|
+
<xsl:choose>
|
|
3200
|
+
<xsl:when test="self::figure">
|
|
3201
|
+
<xsl:apply-templates select="caption/node()"/>
|
|
3202
|
+
</xsl:when>
|
|
3203
|
+
<!-- "table", "listing", "list" are titled -->
|
|
3204
|
+
<xsl:otherwise>
|
|
3205
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
3206
|
+
</xsl:otherwise>
|
|
3207
|
+
</xsl:choose>
|
|
3208
|
+
</fo:block>
|
|
3209
|
+
</fo:block>
|
|
3210
|
+
</xsl:template>
|
|
3211
|
+
|
|
3212
|
+
<!-- ############# -->
|
|
3213
|
+
<!-- Inline Markup -->
|
|
3214
|
+
<!-- ############# -->
|
|
3215
|
+
|
|
3216
|
+
<!-- Semantic inline markup, mostly by font change. An "alert" -->
|
|
3217
|
+
<!-- gets both weight and style, distinct from "em" and "term". -->
|
|
3218
|
+
<xsl:template match="em|pubtitle|taxon|taxon/genus|taxon/species">
|
|
3219
|
+
<fo:inline font-style="italic">
|
|
3220
|
+
<xsl:apply-templates/>
|
|
3221
|
+
</fo:inline>
|
|
3222
|
+
</xsl:template>
|
|
3223
|
+
|
|
3224
|
+
<!-- A "foreign" phrase carries its language into the PDF -->
|
|
3225
|
+
<!-- structure (WCAG 3.1.2, Language of Parts). -->
|
|
3226
|
+
<xsl:template match="foreign">
|
|
3227
|
+
<fo:inline font-style="italic">
|
|
3228
|
+
<xsl:if test="@xml:lang">
|
|
3229
|
+
<xsl:attribute name="xml:lang">
|
|
3230
|
+
<xsl:value-of select="@xml:lang"/>
|
|
3231
|
+
</xsl:attribute>
|
|
3232
|
+
</xsl:if>
|
|
3233
|
+
<xsl:apply-templates/>
|
|
3234
|
+
</fo:inline>
|
|
3235
|
+
</xsl:template>
|
|
3236
|
+
|
|
3237
|
+
<xsl:template match="term">
|
|
3238
|
+
<fo:inline font-weight="bold">
|
|
3239
|
+
<xsl:apply-templates/>
|
|
3240
|
+
</fo:inline>
|
|
3241
|
+
</xsl:template>
|
|
3242
|
+
|
|
3243
|
+
<xsl:template match="alert">
|
|
3244
|
+
<fo:inline font-weight="bold" font-style="italic">
|
|
3245
|
+
<xsl:apply-templates/>
|
|
3246
|
+
</fo:inline>
|
|
3247
|
+
</xsl:template>
|
|
3248
|
+
|
|
3249
|
+
<!-- An "articletitle" is quoted, in the style of CMOS. -->
|
|
3250
|
+
<xsl:template match="articletitle">
|
|
3251
|
+
<xsl:apply-templates select="." mode="lq-character"/>
|
|
3252
|
+
<xsl:apply-templates/>
|
|
3253
|
+
<xsl:apply-templates select="." mode="rq-character"/>
|
|
3254
|
+
</xsl:template>
|
|
3255
|
+
|
|
3256
|
+
<!-- Edits: an "insert" is underlined, a "delete" and a "stale" -->
|
|
3257
|
+
<!-- are struck through. Mirroring the LaTeX conversion, an -->
|
|
3258
|
+
<!-- electronic PDF (the default) colors "insert" green and -->
|
|
3259
|
+
<!-- "delete" red; a print PDF, and "stale" always, stays black. -->
|
|
3260
|
+
<xsl:template match="insert">
|
|
3261
|
+
<fo:inline text-decoration="underline">
|
|
3262
|
+
<xsl:if test="not($b-latex-print)">
|
|
3263
|
+
<xsl:attribute name="color">#00FF00</xsl:attribute>
|
|
3264
|
+
</xsl:if>
|
|
3265
|
+
<xsl:apply-templates/>
|
|
3266
|
+
</fo:inline>
|
|
3267
|
+
</xsl:template>
|
|
3268
|
+
|
|
3269
|
+
<xsl:template match="delete">
|
|
3270
|
+
<fo:inline text-decoration="line-through">
|
|
3271
|
+
<xsl:if test="not($b-latex-print)">
|
|
3272
|
+
<xsl:attribute name="color">red</xsl:attribute>
|
|
3273
|
+
</xsl:if>
|
|
3274
|
+
<xsl:apply-templates/>
|
|
3275
|
+
</fo:inline>
|
|
3276
|
+
</xsl:template>
|
|
3277
|
+
|
|
3278
|
+
<xsl:template match="stale">
|
|
3279
|
+
<fo:inline text-decoration="line-through">
|
|
3280
|
+
<xsl:apply-templates/>
|
|
3281
|
+
</fo:inline>
|
|
3282
|
+
</xsl:template>
|
|
3283
|
+
|
|
3284
|
+
<!-- Abbreviations, acronyms, initialisms: no special typography. -->
|
|
3285
|
+
<xsl:template match="abbr|acro|init">
|
|
3286
|
+
<xsl:apply-templates/>
|
|
3287
|
+
</xsl:template>
|
|
3288
|
+
|
|
3289
|
+
<!-- Keyboard keys, visibly boxed. A @name indexes the Unicode -->
|
|
3290
|
+
<!-- column of the key table in pretext-common.xsl. -->
|
|
3291
|
+
<xsl:template match="kbd[not(@name)]">
|
|
3292
|
+
<fo:inline font-family="{$font-family-monospace}" border="solid 0.5pt #888888" padding-left="2pt" padding-right="2pt">
|
|
3293
|
+
<xsl:value-of select="."/>
|
|
3294
|
+
</fo:inline>
|
|
3295
|
+
</xsl:template>
|
|
3296
|
+
|
|
3297
|
+
<!-- Named keys. Each key glyph stands alone, so the font-family -->
|
|
3298
|
+
<!-- list resolves per glyph: the ASCII keys (#, &, ~, ...) come -->
|
|
3299
|
+
<!-- from the monospace face, matching an unnamed boxed key, while -->
|
|
3300
|
+
<!-- the arrow and symbol keys fall back to the symbol font. The -->
|
|
3301
|
+
<!-- official "enter" code point (U+2BA0) is in no embeddable face, -->
|
|
3302
|
+
<!-- so the classic return symbol (U+21B5) stands in. -->
|
|
3303
|
+
<xsl:template match="kbd[@name]">
|
|
3304
|
+
<xsl:variable name="kbdkey-name" select="@name"/>
|
|
3305
|
+
<fo:inline font-family="{$font-family-monospace}, {$font-family-symbol}" border="solid 0.5pt #888888" padding-left="2pt" padding-right="2pt">
|
|
3306
|
+
<xsl:choose>
|
|
3307
|
+
<xsl:when test="@name = 'enter'">
|
|
3308
|
+
<xsl:text>↵</xsl:text>
|
|
3309
|
+
</xsl:when>
|
|
3310
|
+
<xsl:otherwise>
|
|
3311
|
+
<!-- for-each is just one node, but sets context for key() -->
|
|
3312
|
+
<xsl:for-each select="$kbdkey-table">
|
|
3313
|
+
<xsl:value-of select="key('kbdkey-key', $kbdkey-name)/@unicode"/>
|
|
3314
|
+
</xsl:for-each>
|
|
3315
|
+
</xsl:otherwise>
|
|
3316
|
+
</xsl:choose>
|
|
3317
|
+
</fo:inline>
|
|
3318
|
+
</xsl:template>
|
|
3319
|
+
|
|
3320
|
+
<!-- Implementations of abstract templates from pretext-common.xsl. -->
|
|
3321
|
+
<!-- The generic machinery there (inline verbatim text, bibliography -->
|
|
3322
|
+
<!-- entries, internal markup) calls on these for output-specific -->
|
|
3323
|
+
<!-- font changes. -->
|
|
3324
|
+
<xsl:template name="code-wrapper">
|
|
3325
|
+
<xsl:param name="content"/>
|
|
3326
|
+
<fo:inline font-family="{$font-family-monospace}">
|
|
3327
|
+
<xsl:value-of select="$content"/>
|
|
3328
|
+
</fo:inline>
|
|
3329
|
+
</xsl:template>
|
|
3330
|
+
|
|
3331
|
+
<!-- An inline program fragment ("pf") is monospace, exactly as -->
|
|
3332
|
+
<!-- "c"; syntax highlighting by @language is a refinement. -->
|
|
3333
|
+
<xsl:template match="pf">
|
|
3334
|
+
<xsl:call-template name="code-wrapper">
|
|
3335
|
+
<xsl:with-param name="content">
|
|
3336
|
+
<xsl:value-of select="."/>
|
|
3337
|
+
</xsl:with-param>
|
|
3338
|
+
</xsl:call-template>
|
|
3339
|
+
</xsl:template>
|
|
3340
|
+
|
|
3341
|
+
<!-- An "element" names an XML or HTML element in documentation -->
|
|
3342
|
+
<!-- prose; no other conversion decorates it (the built-in rules -->
|
|
3343
|
+
<!-- apply), so the text just passes through. -->
|
|
3344
|
+
<xsl:template match="element">
|
|
3345
|
+
<xsl:apply-templates/>
|
|
3346
|
+
</xsl:template>
|
|
3347
|
+
|
|
3348
|
+
<xsl:template match="*" mode="italic">
|
|
3349
|
+
<fo:inline font-style="italic">
|
|
3350
|
+
<xsl:apply-templates/>
|
|
3351
|
+
</fo:inline>
|
|
3352
|
+
</xsl:template>
|
|
3353
|
+
|
|
3354
|
+
<xsl:template match="*" mode="bold">
|
|
3355
|
+
<fo:inline font-weight="bold">
|
|
3356
|
+
<xsl:apply-templates/>
|
|
3357
|
+
</fo:inline>
|
|
3358
|
+
</xsl:template>
|
|
3359
|
+
|
|
3360
|
+
<xsl:template match="*" mode="monospace">
|
|
3361
|
+
<fo:inline font-family="{$font-family-monospace}">
|
|
3362
|
+
<xsl:apply-templates/>
|
|
3363
|
+
</fo:inline>
|
|
3364
|
+
</xsl:template>
|
|
3365
|
+
|
|
3366
|
+
<!-- ########## -->
|
|
3367
|
+
<!-- Characters -->
|
|
3368
|
+
<!-- ########## -->
|
|
3369
|
+
|
|
3370
|
+
<!-- pretext-common.xsl implements the elements for special -->
|
|
3371
|
+
<!-- characters, Latin abbreviations, quotation constructions, -->
|
|
3372
|
+
<!-- verbatim snippets ("c", "tag", "tage", "attr"), and logos, -->
|
|
3373
|
+
<!-- in terms of abstract "*-character" templates which receive -->
|
|
3374
|
+
<!-- concrete Unicode values below. So these elements are -->
|
|
3375
|
+
<!-- implemented entirely in common, and need no FO template -->
|
|
3376
|
+
<!-- of their own here. -->
|
|
3377
|
+
|
|
3378
|
+
<!-- An <icon> is a FontAwesome 5 glyph, as in the LaTeX route: the -->
|
|
3379
|
+
<!-- face follows iconinfo/@font-awesome-family and the glyph is -->
|
|
3380
|
+
<!-- the Private-Use codepoint iconinfo/@fa-codepoint. -->
|
|
3381
|
+
<xsl:template match="icon">
|
|
3382
|
+
<xsl:variable name="icon-name" select="string(@name)"/>
|
|
3383
|
+
<!-- for-each is one node, but sets the context for key() -->
|
|
3384
|
+
<xsl:for-each select="$icon-table">
|
|
3385
|
+
<xsl:variable name="info" select="key('icon-key', $icon-name)"/>
|
|
3386
|
+
<xsl:variable name="family">
|
|
3387
|
+
<xsl:choose>
|
|
3388
|
+
<xsl:when test="$info/@font-awesome-family = 'brands'">
|
|
3389
|
+
<xsl:value-of select="$font-family-icon-brands"/>
|
|
3390
|
+
</xsl:when>
|
|
3391
|
+
<xsl:otherwise>
|
|
3392
|
+
<xsl:value-of select="$font-family-icon"/>
|
|
3393
|
+
</xsl:otherwise>
|
|
3394
|
+
</xsl:choose>
|
|
3395
|
+
</xsl:variable>
|
|
3396
|
+
<fo:inline font-family="{$family}">
|
|
3397
|
+
<xsl:value-of select="$info/@fa-codepoint"/>
|
|
3398
|
+
</fo:inline>
|
|
3399
|
+
</xsl:for-each>
|
|
3400
|
+
</xsl:template>
|
|
3401
|
+
|
|
3402
|
+
<!-- The TeX-family logos have no implementation in the imported -->
|
|
3403
|
+
<!-- stylesheets (the HTML conversion styles them with CSS), so -->
|
|
3404
|
+
<!-- they are plain text here. -->
|
|
3405
|
+
<xsl:template match="tex">
|
|
3406
|
+
<xsl:text>TeX</xsl:text>
|
|
3407
|
+
</xsl:template>
|
|
3408
|
+
<xsl:template match="latex">
|
|
3409
|
+
<xsl:text>LaTeX</xsl:text>
|
|
3410
|
+
</xsl:template>
|
|
3411
|
+
|
|
3412
|
+
<!-- Quotation marks follow the document's language: each side -->
|
|
3413
|
+
<!-- resolves the ambient quotation style (primary for double, -->
|
|
3414
|
+
<!-- secondary for single) to its Unicode character, exactly as -->
|
|
3415
|
+
<!-- the HTML conversion does, through the shared lookup. -->
|
|
3416
|
+
<xsl:template match="*" mode="lsq-character">
|
|
3417
|
+
<xsl:call-template name="fo-localized-quote-character">
|
|
3418
|
+
<xsl:with-param name="style">
|
|
3419
|
+
<xsl:apply-templates select="." mode="get-quote-secondary"/>
|
|
3420
|
+
</xsl:with-param>
|
|
3421
|
+
<xsl:with-param name="side" select="'left'"/>
|
|
3422
|
+
</xsl:call-template>
|
|
3423
|
+
</xsl:template>
|
|
3424
|
+
<xsl:template match="*" mode="rsq-character">
|
|
3425
|
+
<xsl:call-template name="fo-localized-quote-character">
|
|
3426
|
+
<xsl:with-param name="style">
|
|
3427
|
+
<xsl:apply-templates select="." mode="get-quote-secondary"/>
|
|
3428
|
+
</xsl:with-param>
|
|
3429
|
+
<xsl:with-param name="side" select="'right'"/>
|
|
3430
|
+
</xsl:call-template>
|
|
3431
|
+
</xsl:template>
|
|
3432
|
+
<xsl:template match="*" mode="lq-character">
|
|
3433
|
+
<xsl:call-template name="fo-localized-quote-character">
|
|
3434
|
+
<xsl:with-param name="style">
|
|
3435
|
+
<xsl:apply-templates select="." mode="get-quote-primary"/>
|
|
3436
|
+
</xsl:with-param>
|
|
3437
|
+
<xsl:with-param name="side" select="'left'"/>
|
|
3438
|
+
</xsl:call-template>
|
|
3439
|
+
</xsl:template>
|
|
3440
|
+
<xsl:template match="*" mode="rq-character">
|
|
3441
|
+
<xsl:call-template name="fo-localized-quote-character">
|
|
3442
|
+
<xsl:with-param name="style">
|
|
3443
|
+
<xsl:apply-templates select="." mode="get-quote-primary"/>
|
|
3444
|
+
</xsl:with-param>
|
|
3445
|
+
<xsl:with-param name="side" select="'right'"/>
|
|
3446
|
+
</xsl:call-template>
|
|
3447
|
+
</xsl:template>
|
|
3448
|
+
|
|
3449
|
+
<!-- Look a quotation mark up in the shared table, then emit it -->
|
|
3450
|
+
<!-- with any narrow no-break space drawn from the symbol font: -->
|
|
3451
|
+
<!-- Latin Modern lacks that glyph, so a literal U+202F would -->
|
|
3452
|
+
<!-- print as a missing-glyph box next to the guillemets. -->
|
|
3453
|
+
<xsl:template name="fo-localized-quote-character">
|
|
3454
|
+
<xsl:param name="style"/>
|
|
3455
|
+
<xsl:param name="side"/>
|
|
3456
|
+
<xsl:variable name="mark">
|
|
3457
|
+
<xsl:apply-templates select="." mode="quote-character-unicode">
|
|
3458
|
+
<xsl:with-param name="style" select="$style"/>
|
|
3459
|
+
<xsl:with-param name="side" select="$side"/>
|
|
3460
|
+
</xsl:apply-templates>
|
|
3461
|
+
</xsl:variable>
|
|
3462
|
+
<xsl:call-template name="isolate-narrow-no-break-space">
|
|
3463
|
+
<xsl:with-param name="text" select="$mark"/>
|
|
3464
|
+
</xsl:call-template>
|
|
3465
|
+
</xsl:template>
|
|
3466
|
+
|
|
3467
|
+
<!-- Emit a string, drawing each narrow no-break space (U+202F) -->
|
|
3468
|
+
<!-- from the symbol font, passing the rest unchanged. -->
|
|
3469
|
+
<xsl:template name="isolate-narrow-no-break-space">
|
|
3470
|
+
<xsl:param name="text"/>
|
|
3471
|
+
<xsl:choose>
|
|
3472
|
+
<xsl:when test="contains($text, ' ')">
|
|
3473
|
+
<xsl:value-of select="substring-before($text, ' ')"/>
|
|
3474
|
+
<xsl:call-template name="narrow-no-break-space-character"/>
|
|
3475
|
+
<xsl:call-template name="isolate-narrow-no-break-space">
|
|
3476
|
+
<xsl:with-param name="text" select="substring-after($text, ' ')"/>
|
|
3477
|
+
</xsl:call-template>
|
|
3478
|
+
</xsl:when>
|
|
3479
|
+
<xsl:otherwise>
|
|
3480
|
+
<xsl:value-of select="$text"/>
|
|
3481
|
+
</xsl:otherwise>
|
|
3482
|
+
</xsl:choose>
|
|
3483
|
+
</xsl:template>
|
|
3484
|
+
|
|
3485
|
+
<!-- The adornments of manually-tagged equations. The star and -->
|
|
3486
|
+
<!-- the maltese cross are missing from the main (serif) face, -->
|
|
3487
|
+
<!-- so they borrow the symbol font. -->
|
|
3488
|
+
<xsl:template name="tag-star">
|
|
3489
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
3490
|
+
<xsl:text>✶</xsl:text>
|
|
3491
|
+
</fo:inline>
|
|
3492
|
+
</xsl:template>
|
|
3493
|
+
<xsl:template name="tag-dagger">
|
|
3494
|
+
<xsl:text>†</xsl:text>
|
|
3495
|
+
</xsl:template>
|
|
3496
|
+
<xsl:template name="tag-daggerdbl">
|
|
3497
|
+
<xsl:text>‡</xsl:text>
|
|
3498
|
+
</xsl:template>
|
|
3499
|
+
<xsl:template name="tag-hash">
|
|
3500
|
+
<xsl:text>#</xsl:text>
|
|
3501
|
+
</xsl:template>
|
|
3502
|
+
<xsl:template name="tag-maltese">
|
|
3503
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
3504
|
+
<xsl:text>✠</xsl:text>
|
|
3505
|
+
</fo:inline>
|
|
3506
|
+
</xsl:template>
|
|
3507
|
+
|
|
3508
|
+
<!-- The Unicode code points below match the HTML conversion. -->
|
|
3509
|
+
<xsl:template name="nbsp-character">
|
|
3510
|
+
<xsl:text> </xsl:text>
|
|
3511
|
+
</xsl:template>
|
|
3512
|
+
<xsl:template name="ndash-character">
|
|
3513
|
+
<xsl:text>–</xsl:text>
|
|
3514
|
+
</xsl:template>
|
|
3515
|
+
<xsl:template name="mdash-character">
|
|
3516
|
+
<xsl:text>—</xsl:text>
|
|
3517
|
+
</xsl:template>
|
|
3518
|
+
<!-- the thin space is missing from the main (serif) face, so it -->
|
|
3519
|
+
<!-- borrows the symbol font, as the narrow no-break space does -->
|
|
3520
|
+
<xsl:template name="thin-space-character">
|
|
3521
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
3522
|
+
<xsl:text> </xsl:text>
|
|
3523
|
+
</fo:inline>
|
|
3524
|
+
</xsl:template>
|
|
3525
|
+
<!-- the narrow no-break space is missing from the main (serif) -->
|
|
3526
|
+
<!-- face, so it borrows the symbol font, as the tombstone does -->
|
|
3527
|
+
<xsl:template name="narrow-no-break-space-character">
|
|
3528
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
3529
|
+
<xsl:text> </xsl:text>
|
|
3530
|
+
</fo:inline>
|
|
3531
|
+
</xsl:template>
|
|
3532
|
+
<!-- the white square brackets are missing from the main (serif) -->
|
|
3533
|
+
<!-- face, so they borrow the symbol font, as the tombstone does -->
|
|
3534
|
+
<xsl:template name="ldblbracket-character">
|
|
3535
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
3536
|
+
<xsl:text>⟦</xsl:text>
|
|
3537
|
+
</fo:inline>
|
|
3538
|
+
</xsl:template>
|
|
3539
|
+
<xsl:template name="rdblbracket-character">
|
|
3540
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
3541
|
+
<xsl:text>⟧</xsl:text>
|
|
3542
|
+
</fo:inline>
|
|
3543
|
+
</xsl:template>
|
|
3544
|
+
<!-- the *mathematical* angle brackets (U+27E8, U+27E9), missing -->
|
|
3545
|
+
<!-- from the main (serif) face, so they borrow the symbol font; -->
|
|
3546
|
+
<!-- the CJK pair (U+3008, U+3009) is in no embedded font at all -->
|
|
3547
|
+
<xsl:template name="langle-character">
|
|
3548
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
3549
|
+
<xsl:text>⟨</xsl:text>
|
|
3550
|
+
</fo:inline>
|
|
3551
|
+
</xsl:template>
|
|
3552
|
+
<xsl:template name="rangle-character">
|
|
3553
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
3554
|
+
<xsl:text>⟩</xsl:text>
|
|
3555
|
+
</fo:inline>
|
|
3556
|
+
</xsl:template>
|
|
3557
|
+
<xsl:template name="ellipsis-character">
|
|
3558
|
+
<xsl:text>…</xsl:text>
|
|
3559
|
+
</xsl:template>
|
|
3560
|
+
<xsl:template name="midpoint-character">
|
|
3561
|
+
<xsl:text>·</xsl:text>
|
|
3562
|
+
</xsl:template>
|
|
3563
|
+
<!-- the swung dash is missing from the main (serif) face, so it -->
|
|
3564
|
+
<!-- borrows the symbol font, as the tombstone does -->
|
|
3565
|
+
<xsl:template name="swungdash-character">
|
|
3566
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
3567
|
+
<xsl:text>⁓</xsl:text>
|
|
3568
|
+
</fo:inline>
|
|
3569
|
+
</xsl:template>
|
|
3570
|
+
<xsl:template name="permille-character">
|
|
3571
|
+
<xsl:text>‰</xsl:text>
|
|
3572
|
+
</xsl:template>
|
|
3573
|
+
<xsl:template name="pilcrow-character">
|
|
3574
|
+
<xsl:text>¶</xsl:text>
|
|
3575
|
+
</xsl:template>
|
|
3576
|
+
<xsl:template name="section-mark-character">
|
|
3577
|
+
<xsl:text>§</xsl:text>
|
|
3578
|
+
</xsl:template>
|
|
3579
|
+
<xsl:template name="minus-character">
|
|
3580
|
+
<xsl:text>−</xsl:text>
|
|
3581
|
+
</xsl:template>
|
|
3582
|
+
<xsl:template name="times-character">
|
|
3583
|
+
<xsl:text>×</xsl:text>
|
|
3584
|
+
</xsl:template>
|
|
3585
|
+
<xsl:template name="solidus-character">
|
|
3586
|
+
<xsl:text>⁄</xsl:text>
|
|
3587
|
+
</xsl:template>
|
|
3588
|
+
<xsl:template name="obelus-character">
|
|
3589
|
+
<xsl:text>÷</xsl:text>
|
|
3590
|
+
</xsl:template>
|
|
3591
|
+
<xsl:template name="plusminus-character">
|
|
3592
|
+
<xsl:text>±</xsl:text>
|
|
3593
|
+
</xsl:template>
|
|
3594
|
+
<xsl:template name="copyright-character">
|
|
3595
|
+
<xsl:text>©</xsl:text>
|
|
3596
|
+
</xsl:template>
|
|
3597
|
+
<!-- the sound-recording and service marks borrow the symbol font -->
|
|
3598
|
+
<xsl:template name="phonomark-character">
|
|
3599
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
3600
|
+
<xsl:text>℗</xsl:text>
|
|
3601
|
+
</fo:inline>
|
|
3602
|
+
</xsl:template>
|
|
3603
|
+
<!-- The copyleft symbol (U+1F12F) is in no embeddable font, so it -->
|
|
3604
|
+
<!-- is built, as in its name, from a reversed "c" (U+2184) set in -->
|
|
3605
|
+
<!-- parentheses. The main font lacks the reversed "c", and it sits -->
|
|
3606
|
+
<!-- between the parentheses with no surrounding space, so it is -->
|
|
3607
|
+
<!-- named from the symbol font explicitly, as the primes are. -->
|
|
3608
|
+
<xsl:template name="copyleft-character">
|
|
3609
|
+
<xsl:text>(</xsl:text>
|
|
3610
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
3611
|
+
<xsl:text>ↄ</xsl:text>
|
|
3612
|
+
</fo:inline>
|
|
3613
|
+
<xsl:text>)</xsl:text>
|
|
3614
|
+
</xsl:template>
|
|
3615
|
+
<xsl:template name="registered-character">
|
|
3616
|
+
<xsl:text>®</xsl:text>
|
|
3617
|
+
</xsl:template>
|
|
3618
|
+
<xsl:template name="trademark-character">
|
|
3619
|
+
<xsl:text>™</xsl:text>
|
|
3620
|
+
</xsl:template>
|
|
3621
|
+
<xsl:template name="servicemark-character">
|
|
3622
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
3623
|
+
<xsl:text>℠</xsl:text>
|
|
3624
|
+
</fo:inline>
|
|
3625
|
+
</xsl:template>
|
|
3626
|
+
<xsl:template name="degree-character">
|
|
3627
|
+
<xsl:text>°</xsl:text>
|
|
3628
|
+
</xsl:template>
|
|
3629
|
+
<!-- the prime and double prime (minutes and seconds, feet and -->
|
|
3630
|
+
<!-- inches) are missing from the main (serif) face; because they -->
|
|
3631
|
+
<!-- sit *within* a measurement, with no surrounding space, FOP's -->
|
|
3632
|
+
<!-- per-word font selection cannot reach the symbol font for them, -->
|
|
3633
|
+
<!-- so each is named explicitly, as the tombstone is. -->
|
|
3634
|
+
<xsl:template name="prime-character">
|
|
3635
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
3636
|
+
<xsl:text>′</xsl:text>
|
|
3637
|
+
</fo:inline>
|
|
3638
|
+
</xsl:template>
|
|
3639
|
+
<xsl:template name="dblprime-character">
|
|
3640
|
+
<fo:inline font-family="{$font-family-symbol}">
|
|
3641
|
+
<xsl:text>″</xsl:text>
|
|
3642
|
+
</fo:inline>
|
|
3643
|
+
</xsl:template>
|
|
3644
|
+
|
|
3645
|
+
<!-- ######### -->
|
|
3646
|
+
<!-- Footnotes -->
|
|
3647
|
+
<!-- ######### -->
|
|
3648
|
+
|
|
3649
|
+
<!-- A "fn" is a native fo:footnote: a superscript mark in the -->
|
|
3650
|
+
<!-- text, and the body, marked again, collected at the bottom of -->
|
|
3651
|
+
<!-- the page above the separator rule defined in the entry -->
|
|
3652
|
+
<!-- template. The footnote number is the serial machinery's. -->
|
|
3653
|
+
<xsl:template match="fn">
|
|
3654
|
+
<xsl:variable name="the-mark">
|
|
3655
|
+
<xsl:apply-templates select="." mode="serial-number"/>
|
|
3656
|
+
</xsl:variable>
|
|
3657
|
+
<fo:footnote>
|
|
3658
|
+
<!-- A fixed fraction of the line-height raises the mark; FOP's -->
|
|
3659
|
+
<!-- "super" keyword shifts so far it inflates the line box and -->
|
|
3660
|
+
<!-- drops a list item's first line below its label. -->
|
|
3661
|
+
<fo:inline baseline-shift="35%" font-size="70%">
|
|
3662
|
+
<xsl:value-of select="$the-mark"/>
|
|
3663
|
+
</fo:inline>
|
|
3664
|
+
<fo:footnote-body>
|
|
3665
|
+
<!-- "text-align-last" keeps the final line ragged: inside a -->
|
|
3666
|
+
<!-- "footnote-body" FOP justifies even the last line, which -->
|
|
3667
|
+
<!-- stretches a one-line note across the whole measure -->
|
|
3668
|
+
<fo:block font-size="80%" text-align="{$text-alignment}" text-align-last="start" space-before="0.25em">
|
|
3669
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
3670
|
+
<fo:inline baseline-shift="35%" font-size="70%">
|
|
3671
|
+
<xsl:value-of select="$the-mark"/>
|
|
3672
|
+
</fo:inline>
|
|
3673
|
+
<xsl:text> </xsl:text>
|
|
3674
|
+
<xsl:apply-templates/>
|
|
3675
|
+
</fo:block>
|
|
3676
|
+
</fo:footnote-body>
|
|
3677
|
+
</fo:footnote>
|
|
3678
|
+
</xsl:template>
|
|
3679
|
+
|
|
3680
|
+
<!-- ########## -->
|
|
3681
|
+
<!-- Hyperlinks -->
|
|
3682
|
+
<!-- ########## -->
|
|
3683
|
+
|
|
3684
|
+
<!-- Each object an "xref" can target gets an @id, the landing -->
|
|
3685
|
+
<!-- spot of an internal link, from the same "unique-id" used to -->
|
|
3686
|
+
<!-- key the mathematics files. (N.B. the natural mode name -->
|
|
3687
|
+
<!-- "id-attribute" belongs to a whole pass of the assembly -->
|
|
3688
|
+
<!-- stylesheet; shadowing it destroys the assembled tree.) -->
|
|
3689
|
+
<xsl:template match="*" mode="link-id-attribute">
|
|
3690
|
+
<xsl:attribute name="id">
|
|
3691
|
+
<xsl:apply-templates select="." mode="unique-id"/>
|
|
3692
|
+
</xsl:attribute>
|
|
3693
|
+
</xsl:template>
|
|
3694
|
+
|
|
3695
|
+
<!-- In an electronic PDF, active links are a conservative dark -->
|
|
3696
|
+
<!-- blue (well above the WCAG contrast threshold on white -->
|
|
3697
|
+
<!-- paper); in a print PDF the color would just be a distracting -->
|
|
3698
|
+
<!-- reminder of links a reader cannot follow, so text stays -->
|
|
3699
|
+
<!-- black, as in the LaTeX conversion. Underlining honors the -->
|
|
3700
|
+
<!-- publisher's link-highlight choice either way. -->
|
|
3701
|
+
<xsl:template name="link-attributes">
|
|
3702
|
+
<xsl:if test="not($b-latex-print)">
|
|
3703
|
+
<xsl:attribute name="color">
|
|
3704
|
+
<xsl:text>#000080</xsl:text>
|
|
3705
|
+
</xsl:attribute>
|
|
3706
|
+
</xsl:if>
|
|
3707
|
+
<xsl:if test="$latex-link-highlight = 'underline'">
|
|
3708
|
+
<xsl:attribute name="text-decoration">
|
|
3709
|
+
<xsl:text>underline</xsl:text>
|
|
3710
|
+
</xsl:attribute>
|
|
3711
|
+
</xsl:if>
|
|
3712
|
+
</xsl:template>
|
|
3713
|
+
|
|
3714
|
+
<!-- A "url" (or "dataurl") is an active external link. Visible -->
|
|
3715
|
+
<!-- text is the element's content, or else the "visual" URL -->
|
|
3716
|
+
<!-- (authored, or manufactured during assembly) in a monospace -->
|
|
3717
|
+
<!-- font. Inside a title the link is inactive, as in the HTML -->
|
|
3718
|
+
<!-- conversion. -->
|
|
3719
|
+
<xsl:template match="url|dataurl">
|
|
3720
|
+
<xsl:variable name="uri">
|
|
3721
|
+
<xsl:choose>
|
|
3722
|
+
<!-- "url" and "dataurl" both support external @href -->
|
|
3723
|
+
<xsl:when test="@href">
|
|
3724
|
+
<xsl:value-of select="@href"/>
|
|
3725
|
+
</xsl:when>
|
|
3726
|
+
<!-- a "dataurl" might be local, @source is -->
|
|
3727
|
+
<!-- indication, so prefix with a local path/URI -->
|
|
3728
|
+
<xsl:when test="self::dataurl and @source">
|
|
3729
|
+
<xsl:value-of select="$external-directory"/>
|
|
3730
|
+
<xsl:value-of select="@source"/>
|
|
3731
|
+
</xsl:when>
|
|
3732
|
+
<!-- empty will be non-functional -->
|
|
3733
|
+
<xsl:otherwise/>
|
|
3734
|
+
</xsl:choose>
|
|
3735
|
+
</xsl:variable>
|
|
3736
|
+
<xsl:variable name="visible-text">
|
|
3737
|
+
<xsl:choose>
|
|
3738
|
+
<xsl:when test="node()">
|
|
3739
|
+
<xsl:apply-templates/>
|
|
3740
|
+
</xsl:when>
|
|
3741
|
+
<xsl:otherwise>
|
|
3742
|
+
<fo:inline font-family="{$font-family-monospace}">
|
|
3743
|
+
<xsl:choose>
|
|
3744
|
+
<xsl:when test="@visual">
|
|
3745
|
+
<xsl:value-of select="@visual"/>
|
|
3746
|
+
</xsl:when>
|
|
3747
|
+
<xsl:otherwise>
|
|
3748
|
+
<xsl:value-of select="$uri"/>
|
|
3749
|
+
</xsl:otherwise>
|
|
3750
|
+
</xsl:choose>
|
|
3751
|
+
</fo:inline>
|
|
3752
|
+
</xsl:otherwise>
|
|
3753
|
+
</xsl:choose>
|
|
3754
|
+
</xsl:variable>
|
|
3755
|
+
<xsl:choose>
|
|
3756
|
+
<xsl:when test="ancestor::title|ancestor::shorttitle|ancestor::subtitle">
|
|
3757
|
+
<xsl:copy-of select="$visible-text"/>
|
|
3758
|
+
</xsl:when>
|
|
3759
|
+
<!-- an empty destination is fatal to FOP -->
|
|
3760
|
+
<xsl:when test="$uri = ''">
|
|
3761
|
+
<xsl:copy-of select="$visible-text"/>
|
|
3762
|
+
</xsl:when>
|
|
3763
|
+
<xsl:otherwise>
|
|
3764
|
+
<!-- the description PDF/UA requires of a link annotation -->
|
|
3765
|
+
<fo:basic-link external-destination="url({$uri})" fox:alt-text="{$uri}">
|
|
3766
|
+
<xsl:call-template name="link-attributes"/>
|
|
3767
|
+
<xsl:copy-of select="$visible-text"/>
|
|
3768
|
+
</fo:basic-link>
|
|
3769
|
+
</xsl:otherwise>
|
|
3770
|
+
</xsl:choose>
|
|
3771
|
+
</xsl:template>
|
|
3772
|
+
|
|
3773
|
+
<!-- An "email" address is an active "mailto:" link. -->
|
|
3774
|
+
<xsl:template match="email">
|
|
3775
|
+
<fo:basic-link external-destination="url(mailto:{normalize-space(.)})" fox:alt-text="mailto:{normalize-space(.)}">
|
|
3776
|
+
<xsl:call-template name="link-attributes"/>
|
|
3777
|
+
<fo:inline font-family="{$font-family-monospace}">
|
|
3778
|
+
<xsl:value-of select="normalize-space(.)"/>
|
|
3779
|
+
</fo:inline>
|
|
3780
|
+
</fo:basic-link>
|
|
3781
|
+
</xsl:template>
|
|
3782
|
+
|
|
3783
|
+
<!-- ################ -->
|
|
3784
|
+
<!-- Cross-References -->
|
|
3785
|
+
<!-- ################ -->
|
|
3786
|
+
|
|
3787
|
+
<!-- pretext-common.xsl implements all of "xref" processing: -->
|
|
3788
|
+
<!-- target identification, error checking, and generation of the -->
|
|
3789
|
+
<!-- visible text. It finishes in the abstract modal "xref-link" -->
|
|
3790
|
+
<!-- template: an active internal link to the @id of the target. -->
|
|
3791
|
+
<!-- A not-yet-implemented target has no @id in the output, and -->
|
|
3792
|
+
<!-- the link is simply dead until its element joins up. -->
|
|
3793
|
+
<!-- "xref" is implemented in common. -->
|
|
3794
|
+
|
|
3795
|
+
|
|
3796
|
+
<xsl:template match="*" mode="xref-link">
|
|
3797
|
+
<xsl:param name="target"/>
|
|
3798
|
+
<xsl:param name="origin"/>
|
|
3799
|
+
<xsl:param name="content"/>
|
|
3800
|
+
<xsl:variable name="the-id">
|
|
3801
|
+
<xsl:apply-templates select="$target" mode="unique-id"/>
|
|
3802
|
+
</xsl:variable>
|
|
3803
|
+
<xsl:choose>
|
|
3804
|
+
<!-- an empty destination is fatal to FOP -->
|
|
3805
|
+
<xsl:when test="$the-id = ''">
|
|
3806
|
+
<xsl:copy-of select="$content"/>
|
|
3807
|
+
</xsl:when>
|
|
3808
|
+
<xsl:otherwise>
|
|
3809
|
+
<!-- The link text doubles as the description PDF/UA -->
|
|
3810
|
+
<!-- requires, taken from the string value of the content -->
|
|
3811
|
+
<!-- so it keeps a real non-breaking space for a reader, -->
|
|
3812
|
+
<!-- before "fix-nbsp" rewrites those spaces for display. -->
|
|
3813
|
+
<fo:basic-link internal-destination="{$the-id}" fox:alt-text="{normalize-space(string($content))}">
|
|
3814
|
+
<xsl:call-template name="link-attributes"/>
|
|
3815
|
+
<xsl:apply-templates select="exsl:node-set($content)" mode="fix-nbsp"/>
|
|
3816
|
+
</fo:basic-link>
|
|
3817
|
+
<!-- Trail the link with the target's page number, when the -->
|
|
3818
|
+
<!-- publisher wants them, via a native XSL-FO page-number -->
|
|
3819
|
+
<!-- citation (no second pass needed). Exceptions echo the -->
|
|
3820
|
+
<!-- LaTeX conversion: a bibliographic citation or an equation -->
|
|
3821
|
+
<!-- number stands alone, and a title is no place for either. -->
|
|
3822
|
+
<xsl:if test="$b-pageref and not($target/self::biblio or $target/self::mrow or $target/self::md or ancestor::title)">
|
|
3823
|
+
<xsl:text>, p. </xsl:text>
|
|
3824
|
+
<fo:page-number-citation ref-id="{$the-id}"/>
|
|
3825
|
+
</xsl:if>
|
|
3826
|
+
</xsl:otherwise>
|
|
3827
|
+
</xsl:choose>
|
|
3828
|
+
</xsl:template>
|
|
3829
|
+
|
|
3830
|
+
<!-- A non-breaking space that ends a word inside an -->
|
|
3831
|
+
<!-- "fo:inline" or "fo:basic-link", with a glyph glued -->
|
|
3832
|
+
<!-- directly after the inline (no intervening space), trips -->
|
|
3833
|
+
<!-- an FOP layout bug: the following glyph is set about 1.8 -->
|
|
3834
|
+
<!-- points too far left and overprints the inline's last -->
|
|
3835
|
+
<!-- character. An "xref" hits this exactly: its text is -->
|
|
3836
|
+
<!-- "Theorem<nbsp>7.3" in a colored link, with an authored -->
|
|
3837
|
+
<!-- comma or period often glued on with no space. Recasting -->
|
|
3838
|
+
<!-- the U+00A0 as an "fo:character" that is not a word space -->
|
|
3839
|
+
<!-- lets FOP advance normally, while the reference text still -->
|
|
3840
|
+
<!-- will not break across lines. The copy is otherwise an -->
|
|
3841
|
+
<!-- identity transform; run it only on link text, where the -->
|
|
3842
|
+
<!-- inline boundary and the glued punctuation coincide. -->
|
|
3843
|
+
<xsl:template match="node()|@*" mode="fix-nbsp">
|
|
3844
|
+
<xsl:copy>
|
|
3845
|
+
<xsl:apply-templates select="node()|@*" mode="fix-nbsp"/>
|
|
3846
|
+
</xsl:copy>
|
|
3847
|
+
</xsl:template>
|
|
3848
|
+
|
|
3849
|
+
<xsl:template match="text()" mode="fix-nbsp">
|
|
3850
|
+
<xsl:call-template name="nbsp-to-fo-character">
|
|
3851
|
+
<xsl:with-param name="text" select="."/>
|
|
3852
|
+
</xsl:call-template>
|
|
3853
|
+
</xsl:template>
|
|
3854
|
+
|
|
3855
|
+
<!-- Emit text, but with each U+00A0 replaced by a non-word-space -->
|
|
3856
|
+
<!-- "fo:character", recursing across every occurrence. -->
|
|
3857
|
+
<xsl:template name="nbsp-to-fo-character">
|
|
3858
|
+
<xsl:param name="text"/>
|
|
3859
|
+
<xsl:choose>
|
|
3860
|
+
<xsl:when test="contains($text, ' ')">
|
|
3861
|
+
<xsl:value-of select="substring-before($text, ' ')"/>
|
|
3862
|
+
<fo:character character=" " treat-as-word-space="false"/>
|
|
3863
|
+
<xsl:call-template name="nbsp-to-fo-character">
|
|
3864
|
+
<xsl:with-param name="text" select="substring-after($text, ' ')"/>
|
|
3865
|
+
</xsl:call-template>
|
|
3866
|
+
</xsl:when>
|
|
3867
|
+
<xsl:otherwise>
|
|
3868
|
+
<xsl:value-of select="$text"/>
|
|
3869
|
+
</xsl:otherwise>
|
|
3870
|
+
</xsl:choose>
|
|
3871
|
+
</xsl:template>
|
|
3872
|
+
|
|
3873
|
+
<!-- The cross-references that sit inside display mathematics (an -->
|
|
3874
|
+
<!-- "xref" is schema-allowed in an "md", through an "mrow" or a -->
|
|
3875
|
+
<!-- single-line "md", but never in an inline "m"), keyed by the -->
|
|
3876
|
+
<!-- "@ref" they carry, so a destination is named just once even -->
|
|
3877
|
+
<!-- when several references share a target. -->
|
|
3878
|
+
<xsl:key name="math-cross-reference"
|
|
3879
|
+
match="xref[ancestor::md]"
|
|
3880
|
+
use="@ref"/>
|
|
3881
|
+
|
|
3882
|
+
<!-- FOP resolves its own internal links directly and creates no -->
|
|
3883
|
+
<!-- named destinations; but a cross-reference inside mathematics -->
|
|
3884
|
+
<!-- becomes an SVG "a" (see "math.cross-references" in -->
|
|
3885
|
+
<!-- extract-math.xsl) that FOP compiles into a GoTo a *named* -->
|
|
3886
|
+
<!-- destination. So, in "fo:declarations", name a destination -->
|
|
3887
|
+
<!-- for the target of each such reference, once per target; -->
|
|
3888
|
+
<!-- "fox:destination" aims at the element carrying that id, -->
|
|
3889
|
+
<!-- wherever it sits. -->
|
|
3890
|
+
<xsl:template name="math-cross-reference-destinations">
|
|
3891
|
+
<xsl:for-each select="$document-root//xref[ancestor::md and id(@ref)]">
|
|
3892
|
+
<xsl:if test="count(. | key('math-cross-reference', @ref)[1]) = 1">
|
|
3893
|
+
<xsl:variable name="dest-id">
|
|
3894
|
+
<xsl:apply-templates select="id(@ref)" mode="unique-id"/>
|
|
3895
|
+
</xsl:variable>
|
|
3896
|
+
<fox:destination internal-destination="{$dest-id}"/>
|
|
3897
|
+
</xsl:if>
|
|
3898
|
+
</xsl:for-each>
|
|
3899
|
+
</xsl:template>
|
|
3900
|
+
|
|
3901
|
+
<!-- Hard-coded numbers, as in the HTML conversion: the number of -->
|
|
3902
|
+
<!-- the target, prefixed by a part number when the reference -->
|
|
3903
|
+
<!-- crosses a part boundary under "structural" part numbering. -->
|
|
3904
|
+
<xsl:template match="*" mode="xref-number">
|
|
3905
|
+
<xsl:param name="xref" select="/.."/>
|
|
3906
|
+
<xsl:variable name="needs-part-prefix">
|
|
3907
|
+
<xsl:apply-templates select="." mode="crosses-part-boundary">
|
|
3908
|
+
<xsl:with-param name="xref" select="$xref"/>
|
|
3909
|
+
</xsl:apply-templates>
|
|
3910
|
+
</xsl:variable>
|
|
3911
|
+
<xsl:if test="$needs-part-prefix = 'true'">
|
|
3912
|
+
<xsl:apply-templates select="ancestor::part" mode="serial-number"/>
|
|
3913
|
+
<xsl:text>.</xsl:text>
|
|
3914
|
+
</xsl:if>
|
|
3915
|
+
<xsl:apply-templates select="." mode="number"/>
|
|
3916
|
+
</xsl:template>
|
|
3917
|
+
|
|
3918
|
+
<!-- The exception: a local @tag on display mathematics -->
|
|
3919
|
+
<xsl:template match="mrow[@tag]" mode="xref-number">
|
|
3920
|
+
<xsl:apply-templates select="@tag" mode="tag-symbol"/>
|
|
3921
|
+
</xsl:template>
|
|
3922
|
+
|
|
3923
|
+
<xsl:template match="md[@pi:authored-one-line and mrow/@tag]" mode="xref-number">
|
|
3924
|
+
<xsl:apply-templates select="mrow/@tag" mode="tag-symbol"/>
|
|
3925
|
+
</xsl:template>
|
|
3926
|
+
|
|
3927
|
+
<!-- ########### -->
|
|
3928
|
+
<!-- Mathematics -->
|
|
3929
|
+
<!-- ########### -->
|
|
3930
|
+
|
|
3931
|
+
<!-- Each math element looks up its MathJax-produced SVG in the -->
|
|
3932
|
+
<!-- $math-repr file by its "unique-id" (the EPUB model), and the -->
|
|
3933
|
+
<!-- SVG embeds in the page as an fo:instream-foreign-object. -->
|
|
3934
|
+
<!-- MathJax sizes its SVG in "ex" units of its TeX fonts, where -->
|
|
3935
|
+
<!-- one "ex" is 0.442em (visible in any "viewBox", which uses -->
|
|
3936
|
+
<!-- thousandths of an em). Batik, FOP's SVG engine, cannot use -->
|
|
3937
|
+
<!-- "ex" lengths, nor does FOP scale an SVG to a "content-width", -->
|
|
3938
|
+
<!-- so all measurements convert to points, via the body font -->
|
|
3939
|
+
<!-- size, and are written directly onto the SVG element. -->
|
|
3940
|
+
<xsl:variable name="mathjax-em-per-ex" select="0.442"/>
|
|
3941
|
+
<!-- $font-size is a number with "pt" attached -->
|
|
3942
|
+
<xsl:variable name="math-points-per-ex"
|
|
3943
|
+
select="$mathjax-em-per-ex * number(substring-before($font-size, 'pt'))"/>
|
|
3944
|
+
|
|
3945
|
+
<!-- For inline math, the CSS "vertical-align" drop below the -->
|
|
3946
|
+
<!-- baseline (on the SVG's @style) carries over directly as the -->
|
|
3947
|
+
<!-- FO "alignment-adjust": FOP raises the object by the length, -->
|
|
3948
|
+
<!-- so the (negative) drop lowers it below the baseline, exactly -->
|
|
3949
|
+
<!-- as in CSS (verified empirically, 2026-06-11). -->
|
|
3950
|
+
<xsl:template match="m|me|men|md|mdn">
|
|
3951
|
+
<xsl:variable name="id">
|
|
3952
|
+
<xsl:apply-templates select="." mode="unique-id"/>
|
|
3953
|
+
</xsl:variable>
|
|
3954
|
+
<xsl:variable name="svg" select="$math-repr/pi:math[@id = $id]/div[@class = 'svg']/svg:svg"/>
|
|
3955
|
+
<xsl:variable name="speech" select="normalize-space($speech-repr/pi:math[@id = $id]/div[@class = 'speech'])"/>
|
|
3956
|
+
<!-- A display fills the full text measure only when no -->
|
|
3957
|
+
<!-- ancestor narrows the line: a "sidebyside" panel, an -->
|
|
3958
|
+
<!-- "ol"/"ul"/"dl" list item, a "blockquote", a "tabular" -->
|
|
3959
|
+
<!-- cell, a "task", or a multicolumn "exercisegroup" each -->
|
|
3960
|
+
<!-- reduce the width (and a cell's width is not known here -->
|
|
3961
|
+
<!-- in points). -->
|
|
3962
|
+
<xsl:variable name="b-full-measure" select="not(ancestor::sidebyside or ancestor::ol or ancestor::ul or ancestor::dl or ancestor::blockquote or ancestor::tabular or ancestor::task or ancestor::exercisegroup[@cols])"/>
|
|
3963
|
+
<xsl:variable name="width-points">
|
|
3964
|
+
<xsl:choose>
|
|
3965
|
+
<xsl:when test="contains($svg/@width, 'ex')">
|
|
3966
|
+
<xsl:value-of select="number(substring-before($svg/@width, 'ex')) * $math-points-per-ex"/>
|
|
3967
|
+
</xsl:when>
|
|
3968
|
+
<!-- a wide, aligned display arrives as width="100%" with -->
|
|
3969
|
+
<!-- no viewBox and its true width as a "min-width" in the -->
|
|
3970
|
+
<!-- @style; MathJax's own layout then centers the body and -->
|
|
3971
|
+
<!-- drives any tag to the right edge of whatever width we -->
|
|
3972
|
+
<!-- assign. At the full text measure that reproduces the -->
|
|
3973
|
+
<!-- LaTeX result (tag at the margin); in a narrower -->
|
|
3974
|
+
<!-- container we cannot know the available width in points, -->
|
|
3975
|
+
<!-- so we fall back to the content (min-width) and let -->
|
|
3976
|
+
<!-- "text-align-last" center it. -->
|
|
3977
|
+
<xsl:when test="contains($svg/@style, 'min-width:')">
|
|
3978
|
+
<xsl:variable name="content-width-points" select="number(substring-before(substring-after($svg/@style, 'min-width:'), 'ex')) * $math-points-per-ex"/>
|
|
3979
|
+
<xsl:choose>
|
|
3980
|
+
<xsl:when test="$b-full-measure and ($content-width-points < $text-width-points)">
|
|
3981
|
+
<xsl:value-of select="$text-width-points"/>
|
|
3982
|
+
</xsl:when>
|
|
3983
|
+
<xsl:otherwise>
|
|
3984
|
+
<xsl:value-of select="$content-width-points"/>
|
|
3985
|
+
</xsl:otherwise>
|
|
3986
|
+
</xsl:choose>
|
|
3987
|
+
</xsl:when>
|
|
3988
|
+
<!-- last resort: the third entry of the @viewBox, in -->
|
|
3989
|
+
<!-- thousandths of an em -->
|
|
3990
|
+
<xsl:otherwise>
|
|
3991
|
+
<xsl:variable name="past-origin" select="substring-after(substring-after(normalize-space($svg/@viewBox), ' '), ' ')"/>
|
|
3992
|
+
<xsl:value-of select="(number(substring-before($past-origin, ' ')) div 1000) * number(substring-before($font-size, 'pt'))"/>
|
|
3993
|
+
</xsl:otherwise>
|
|
3994
|
+
</xsl:choose>
|
|
3995
|
+
</xsl:variable>
|
|
3996
|
+
<xsl:variable name="height-points"
|
|
3997
|
+
select="number(substring-before($svg/@height, 'ex')) * $math-points-per-ex"/>
|
|
3998
|
+
<!-- a display is centered, but when it is wider than the -->
|
|
3999
|
+
<!-- text measure, flushing it left lets it overrun only -->
|
|
4000
|
+
<!-- the right margin rather than both -->
|
|
4001
|
+
<xsl:variable name="display-align">
|
|
4002
|
+
<xsl:choose>
|
|
4003
|
+
<xsl:when test="$width-points > $text-width-points">left</xsl:when>
|
|
4004
|
+
<xsl:otherwise>center</xsl:otherwise>
|
|
4005
|
+
</xsl:choose>
|
|
4006
|
+
</xsl:variable>
|
|
4007
|
+
<!-- the number or symbol of the display's first numbered or -->
|
|
4008
|
+
<!-- tagged "mrow" (@pi:numbered="yes" or @tag); empty for -->
|
|
4009
|
+
<!-- inline math (no "mrow") and fully unnumbered displays. -->
|
|
4010
|
+
<xsl:variable name="numbered-row" select="mrow[@pi:numbered = 'yes' or @tag][1]"/>
|
|
4011
|
+
<xsl:variable name="eqn-number">
|
|
4012
|
+
<xsl:choose>
|
|
4013
|
+
<xsl:when test="$numbered-row/@tag">
|
|
4014
|
+
<xsl:apply-templates select="$numbered-row/@tag" mode="tag-symbol"/>
|
|
4015
|
+
</xsl:when>
|
|
4016
|
+
<xsl:otherwise>
|
|
4017
|
+
<xsl:apply-templates select="$numbered-row" mode="number"/>
|
|
4018
|
+
</xsl:otherwise>
|
|
4019
|
+
</xsl:choose>
|
|
4020
|
+
</xsl:variable>
|
|
4021
|
+
<xsl:choose>
|
|
4022
|
+
<xsl:when test="$svg and self::m">
|
|
4023
|
+
<!-- for math sitting on the baseline (e.g. a lone digit), -->
|
|
4024
|
+
<!-- MathJax writes "vertical-align: 0;", unitless, and the -->
|
|
4025
|
+
<!-- parse of the "ex" quantity comes up empty, not zero -->
|
|
4026
|
+
<xsl:variable name="drop-raw" select="substring-before(substring-after($svg/@style, 'vertical-align:'), 'ex')"/>
|
|
4027
|
+
<xsl:variable name="drop-ex">
|
|
4028
|
+
<xsl:choose>
|
|
4029
|
+
<xsl:when test="contains($svg/@style, 'vertical-align:') and not(string(number($drop-raw)) = 'NaN')">
|
|
4030
|
+
<xsl:value-of select="number($drop-raw)"/>
|
|
4031
|
+
</xsl:when>
|
|
4032
|
+
<xsl:otherwise>0</xsl:otherwise>
|
|
4033
|
+
</xsl:choose>
|
|
4034
|
+
</xsl:variable>
|
|
4035
|
+
<fo:instream-foreign-object alignment-adjust="{format-number($drop-ex * $math-points-per-ex, '0.####')}pt">
|
|
4036
|
+
<xsl:if test="not($speech = '')">
|
|
4037
|
+
<xsl:attribute name="fox:alt-text">
|
|
4038
|
+
<xsl:value-of select="$speech"/>
|
|
4039
|
+
</xsl:attribute>
|
|
4040
|
+
</xsl:if>
|
|
4041
|
+
<xsl:apply-templates select="$svg" mode="svg-meld">
|
|
4042
|
+
<xsl:with-param name="width-points" select="$width-points"/>
|
|
4043
|
+
<xsl:with-param name="height-points" select="$height-points"/>
|
|
4044
|
+
</xsl:apply-templates>
|
|
4045
|
+
</fo:instream-foreign-object>
|
|
4046
|
+
</xsl:when>
|
|
4047
|
+
<!-- display mathematics in its own block; absorbed -->
|
|
4048
|
+
<!-- clause-ending punctuation is already in the SVG. -->
|
|
4049
|
+
<!-- "text-align-last" repeats the choice because a -->
|
|
4050
|
+
<!-- justified paragraph passes its own down to this lone -->
|
|
4051
|
+
<!-- line, which would otherwise justify (left-pin) the SVG -->
|
|
4052
|
+
<xsl:when test="$svg">
|
|
4053
|
+
<!-- a display wider than the measure cannot be placed well; -->
|
|
4054
|
+
<!-- warn the author, by number when there is one, and report -->
|
|
4055
|
+
<!-- its location -->
|
|
4056
|
+
<xsl:if test="$width-points > $text-width-points">
|
|
4057
|
+
<xsl:message>
|
|
4058
|
+
<xsl:text>PTX:WARNING: a display </xsl:text>
|
|
4059
|
+
<xsl:if test="not(normalize-space($eqn-number) = '')">
|
|
4060
|
+
<xsl:text>(</xsl:text>
|
|
4061
|
+
<xsl:value-of select="normalize-space($eqn-number)"/>
|
|
4062
|
+
<xsl:text>) </xsl:text>
|
|
4063
|
+
</xsl:if>
|
|
4064
|
+
<xsl:text>is wider than the text and overruns the right margin in the XSL-FO output</xsl:text>
|
|
4065
|
+
</xsl:message>
|
|
4066
|
+
<xsl:apply-templates select="." mode="location-report"/>
|
|
4067
|
+
</xsl:if>
|
|
4068
|
+
<fo:block text-align="{$display-align}" text-align-last="{$display-align}" space-before="0.5em" space-after="0.5em">
|
|
4069
|
+
<!-- an over-wide numbered display is a centered body in a -->
|
|
4070
|
+
<!-- "min-width" SVG, so its body sits one number-width in -->
|
|
4071
|
+
<!-- from the left. At the full measure (inherited -->
|
|
4072
|
+
<!-- start-indent zero) pull left by a conservative under- -->
|
|
4073
|
+
<!-- estimate of that width, flushing the body toward the -->
|
|
4074
|
+
<!-- margin without crossing it -->
|
|
4075
|
+
<xsl:if test="$b-full-measure and ($width-points > $text-width-points) and contains($svg/@style, 'min-width:') and not(normalize-space($eqn-number) = '')">
|
|
4076
|
+
<xsl:attribute name="start-indent">
|
|
4077
|
+
<xsl:text>-</xsl:text>
|
|
4078
|
+
<xsl:value-of select="format-number((string-length(normalize-space($eqn-number)) + 2) * 0.5 * number(substring-before($font-size, 'pt')), '0.##')"/>
|
|
4079
|
+
<xsl:text>pt</xsl:text>
|
|
4080
|
+
</xsl:attribute>
|
|
4081
|
+
</xsl:if>
|
|
4082
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
4083
|
+
<!-- an "xref" targets a constituent "mrow", so each -->
|
|
4084
|
+
<!-- contributes an invisible anchor -->
|
|
4085
|
+
<xsl:for-each select="mrow">
|
|
4086
|
+
<fo:inline>
|
|
4087
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
4088
|
+
</fo:inline>
|
|
4089
|
+
</xsl:for-each>
|
|
4090
|
+
<fo:instream-foreign-object>
|
|
4091
|
+
<xsl:if test="not($speech = '')">
|
|
4092
|
+
<xsl:attribute name="fox:alt-text">
|
|
4093
|
+
<xsl:value-of select="$speech"/>
|
|
4094
|
+
</xsl:attribute>
|
|
4095
|
+
</xsl:if>
|
|
4096
|
+
<xsl:apply-templates select="$svg" mode="svg-meld">
|
|
4097
|
+
<xsl:with-param name="width-points" select="$width-points"/>
|
|
4098
|
+
<xsl:with-param name="height-points" select="$height-points"/>
|
|
4099
|
+
</xsl:apply-templates>
|
|
4100
|
+
</fo:instream-foreign-object>
|
|
4101
|
+
</fo:block>
|
|
4102
|
+
</xsl:when>
|
|
4103
|
+
<!-- absent a math representations file (a bare "-f fo" -->
|
|
4104
|
+
<!-- build, with no $mathfile), a placeholder -->
|
|
4105
|
+
<xsl:otherwise>
|
|
4106
|
+
<xsl:apply-templates select="." mode="math-placeholder"/>
|
|
4107
|
+
</xsl:otherwise>
|
|
4108
|
+
</xsl:choose>
|
|
4109
|
+
</xsl:template>
|
|
4110
|
+
|
|
4111
|
+
<!-- Assembly hoists an "intertext" out of its "md", to sit among -->
|
|
4112
|
+
<!-- the children of the paragraph, between two displays; its -->
|
|
4113
|
+
<!-- prose just continues the paragraph. -->
|
|
4114
|
+
<xsl:template match="pi:intertext">
|
|
4115
|
+
<xsl:apply-templates/>
|
|
4116
|
+
</xsl:template>
|
|
4117
|
+
|
|
4118
|
+
<!-- A copy of the SVG with computed sizes: the "ex" lengths of -->
|
|
4119
|
+
<!-- @width, @height, and @style drop, replaced by point lengths; -->
|
|
4120
|
+
<!-- the retained @viewBox supplies the aspect ratio. -->
|
|
4121
|
+
<xsl:template match="svg:svg" mode="svg-meld">
|
|
4122
|
+
<xsl:param name="width-points"/>
|
|
4123
|
+
<xsl:param name="height-points"/>
|
|
4124
|
+
<xsl:copy>
|
|
4125
|
+
<xsl:copy-of select="@*[not(name() = 'style') and not(name() = 'width') and not(name() = 'height')]"/>
|
|
4126
|
+
<xsl:attribute name="width">
|
|
4127
|
+
<xsl:value-of select="format-number($width-points, '0.####')"/>
|
|
4128
|
+
<xsl:text>pt</xsl:text>
|
|
4129
|
+
</xsl:attribute>
|
|
4130
|
+
<xsl:attribute name="height">
|
|
4131
|
+
<xsl:value-of select="format-number($height-points, '0.####')"/>
|
|
4132
|
+
<xsl:text>pt</xsl:text>
|
|
4133
|
+
</xsl:attribute>
|
|
4134
|
+
<xsl:copy-of select="node()"/>
|
|
4135
|
+
</xsl:copy>
|
|
4136
|
+
</xsl:template>
|
|
4137
|
+
|
|
4138
|
+
<!-- Placeholders: the authored LaTeX, visibly boxed, in a -->
|
|
4139
|
+
<!-- monospace font. -->
|
|
4140
|
+
<xsl:template match="m" mode="math-placeholder">
|
|
4141
|
+
<fo:inline font-family="{$font-family-monospace}" border="solid 0.5pt #888888" padding-left="2pt" padding-right="2pt">
|
|
4142
|
+
<xsl:value-of select="."/>
|
|
4143
|
+
</fo:inline>
|
|
4144
|
+
</xsl:template>
|
|
4145
|
+
|
|
4146
|
+
<!-- Assembly rewrites every display to "md", so that is the only -->
|
|
4147
|
+
<!-- form seen here. Each "mrow" is one line of the display: emit -->
|
|
4148
|
+
<!-- it as its own block with whitespace normalized (the raw string -->
|
|
4149
|
+
<!-- value carried the source indentation), and glue the clause- -->
|
|
4150
|
+
<!-- ending punctuation absorbed by the display to the final row -->
|
|
4151
|
+
<!-- rather than leaving it stranded after that indentation. -->
|
|
4152
|
+
<xsl:template match="md" mode="math-placeholder">
|
|
4153
|
+
<fo:block font-family="{$font-family-monospace}"
|
|
4154
|
+
border="solid 0.5pt #888888"
|
|
4155
|
+
padding="2pt"
|
|
4156
|
+
space-before="0.5em"
|
|
4157
|
+
space-after="0.5em"
|
|
4158
|
+
text-align="center">
|
|
4159
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
4160
|
+
<xsl:for-each select="mrow">
|
|
4161
|
+
<fo:block>
|
|
4162
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
4163
|
+
<xsl:value-of select="normalize-space(.)"/>
|
|
4164
|
+
<xsl:if test="position() = last()">
|
|
4165
|
+
<xsl:apply-templates select="parent::md" mode="get-clause-punctuation-mark"/>
|
|
4166
|
+
</xsl:if>
|
|
4167
|
+
</fo:block>
|
|
4168
|
+
</xsl:for-each>
|
|
4169
|
+
</fo:block>
|
|
4170
|
+
</xsl:template>
|
|
4171
|
+
|
|
4172
|
+
<!-- ############ -->
|
|
4173
|
+
<!-- Author Tools -->
|
|
4174
|
+
<!-- ############ -->
|
|
4175
|
+
|
|
4176
|
+
<!-- An author-tools warning, placed in the margin by the HTML -->
|
|
4177
|
+
<!-- conversion. Quietly dropped here, for now: margin notes -->
|
|
4178
|
+
<!-- await a layout treatment. The named template must exist, -->
|
|
4179
|
+
<!-- since a missing named template is a *fatal* runtime error. -->
|
|
4180
|
+
<xsl:template name="margin-warning">
|
|
4181
|
+
<xsl:param name="warning"/>
|
|
4182
|
+
</xsl:template>
|
|
4183
|
+
|
|
4184
|
+
<!-- ################################### -->
|
|
4185
|
+
<!-- Static Forms of Interactive Content -->
|
|
4186
|
+
<!-- ################################### -->
|
|
4187
|
+
|
|
4188
|
+
<!-- The static representations built by pretext-runestone-static.xsl -->
|
|
4189
|
+
<!-- (and by server-rendered problems, e.g. MyOpenMath and STACK) can -->
|
|
4190
|
+
<!-- carry pieces of the original interactive markup. -->
|
|
4191
|
+
|
|
4192
|
+
<!-- In the generated solution of a cardsort or matching problem, -->
|
|
4193
|
+
<!-- "premise" and "response" are transparent wrappers within the -->
|
|
4194
|
+
<!-- list structure. -->
|
|
4195
|
+
<xsl:template match="premise|response">
|
|
4196
|
+
<xsl:apply-templates/>
|
|
4197
|
+
</xsl:template>
|
|
4198
|
+
|
|
4199
|
+
<!-- A server-rendered problem's text-entry blank arrives as an -->
|
|
4200
|
+
<!-- XHTML-flavored "input" with a width in characters; on paper -->
|
|
4201
|
+
<!-- it is a fill-in blank of (about) the same width. -->
|
|
4202
|
+
<xsl:template match="input[@type = 'text']">
|
|
4203
|
+
<xsl:variable name="characters">
|
|
4204
|
+
<xsl:choose>
|
|
4205
|
+
<xsl:when test="starts-with(@style, 'width:') and contains(@style, 'ch')">
|
|
4206
|
+
<xsl:value-of select="substring-before(substring-after(@style, 'width:'), 'ch')"/>
|
|
4207
|
+
</xsl:when>
|
|
4208
|
+
<xsl:otherwise>
|
|
4209
|
+
<xsl:text>10</xsl:text>
|
|
4210
|
+
</xsl:otherwise>
|
|
4211
|
+
</xsl:choose>
|
|
4212
|
+
</xsl:variable>
|
|
4213
|
+
<fo:leader leader-pattern="rule"
|
|
4214
|
+
rule-thickness="0.5pt"
|
|
4215
|
+
rule-style="solid"
|
|
4216
|
+
leader-length="{format-number(0.55 * $characters, '0.##')}em"/>
|
|
4217
|
+
</xsl:template>
|
|
4218
|
+
|
|
4219
|
+
<!-- more XHTML scraps: a "div" is a transparent grouping, -->
|
|
4220
|
+
<!-- and a "br" abandons the current line -->
|
|
4221
|
+
<xsl:template match="div">
|
|
4222
|
+
<xsl:apply-templates/>
|
|
4223
|
+
</xsl:template>
|
|
4224
|
+
|
|
4225
|
+
<xsl:template match="br">
|
|
4226
|
+
<fo:block/>
|
|
4227
|
+
</xsl:template>
|
|
4228
|
+
|
|
4229
|
+
<!-- An author-supplied "static" representation is exactly what -->
|
|
4230
|
+
<!-- the printed form of an "interactive" should show. -->
|
|
4231
|
+
<xsl:template match="static">
|
|
4232
|
+
<xsl:apply-templates select="*"/>
|
|
4233
|
+
</xsl:template>
|
|
4234
|
+
|
|
4235
|
+
<!-- #################### -->
|
|
4236
|
+
<!-- Literate Programming -->
|
|
4237
|
+
<!-- #################### -->
|
|
4238
|
+
|
|
4239
|
+
<!-- A "fragment" of a literate program: a heading line with the -->
|
|
4240
|
+
<!-- traditional angle-bracket name and defined-to-be symbol, then -->
|
|
4241
|
+
<!-- verbatim "code" interleaved with "fragref" pointers to other -->
|
|
4242
|
+
<!-- fragments. -->
|
|
4243
|
+
<xsl:template match="fragment">
|
|
4244
|
+
<fo:block space-before="1em" space-after="1em">
|
|
4245
|
+
<xsl:apply-templates select="." mode="link-id-attribute"/>
|
|
4246
|
+
<fo:block>
|
|
4247
|
+
<xsl:call-template name="langle-character"/>
|
|
4248
|
+
<xsl:apply-templates select="." mode="number"/>
|
|
4249
|
+
<xsl:text> </xsl:text>
|
|
4250
|
+
<xsl:apply-templates select="." mode="title-full"/>
|
|
4251
|
+
<xsl:call-template name="rangle-character"/>
|
|
4252
|
+
<xsl:text> </xsl:text>
|
|
4253
|
+
<xsl:text>≡</xsl:text>
|
|
4254
|
+
</fo:block>
|
|
4255
|
+
<xsl:if test="@filename">
|
|
4256
|
+
<fo:block>
|
|
4257
|
+
<xsl:text>Root of file: </xsl:text>
|
|
4258
|
+
<fo:inline font-family="{$font-family-monospace}">
|
|
4259
|
+
<xsl:value-of select="@filename"/>
|
|
4260
|
+
</fo:inline>
|
|
4261
|
+
</fo:block>
|
|
4262
|
+
</xsl:if>
|
|
4263
|
+
<xsl:apply-templates select="code|fragref"/>
|
|
4264
|
+
</fo:block>
|
|
4265
|
+
</xsl:template>
|
|
4266
|
+
|
|
4267
|
+
<!-- code of a fragment displays verbatim; whitespace-only chunks -->
|
|
4268
|
+
<!-- (text between two adjacent "fragref") just disappear -->
|
|
4269
|
+
<xsl:template match="fragment/code">
|
|
4270
|
+
<xsl:if test="not(normalize-space(.) = '')">
|
|
4271
|
+
<xsl:call-template name="verbatim-block">
|
|
4272
|
+
<xsl:with-param name="content">
|
|
4273
|
+
<xsl:call-template name="sanitize-text">
|
|
4274
|
+
<xsl:with-param name="text" select="."/>
|
|
4275
|
+
</xsl:call-template>
|
|
4276
|
+
</xsl:with-param>
|
|
4277
|
+
</xsl:call-template>
|
|
4278
|
+
</xsl:if>
|
|
4279
|
+
</xsl:template>
|
|
4280
|
+
|
|
4281
|
+
<!-- A "fragref" points to another fragment: its angle-bracket -->
|
|
4282
|
+
<!-- name, with the number and page of the target, linked. -->
|
|
4283
|
+
<xsl:template match="fragref">
|
|
4284
|
+
<xsl:variable name="target" select="id(@ref)"/>
|
|
4285
|
+
<xsl:variable name="the-id">
|
|
4286
|
+
<xsl:apply-templates select="$target" mode="unique-id"/>
|
|
4287
|
+
</xsl:variable>
|
|
4288
|
+
<fo:block start-indent="2em">
|
|
4289
|
+
<xsl:call-template name="langle-character"/>
|
|
4290
|
+
<xsl:apply-templates select="$target" mode="title-full"/>
|
|
4291
|
+
<xsl:text> </xsl:text>
|
|
4292
|
+
<fo:inline font-size="70%">
|
|
4293
|
+
<xsl:apply-templates select="$target" mode="number"/>
|
|
4294
|
+
<xsl:text> [</xsl:text>
|
|
4295
|
+
<fo:basic-link internal-destination="{$the-id}" fox:alt-text="page of this fragment">
|
|
4296
|
+
<xsl:call-template name="link-attributes"/>
|
|
4297
|
+
<fo:page-number-citation ref-id="{$the-id}"/>
|
|
4298
|
+
</fo:basic-link>
|
|
4299
|
+
<xsl:text>]</xsl:text>
|
|
4300
|
+
</fo:inline>
|
|
4301
|
+
<xsl:call-template name="rangle-character"/>
|
|
4302
|
+
</fo:block>
|
|
4303
|
+
</xsl:template>
|
|
4304
|
+
|
|
4305
|
+
<!-- ############### -->
|
|
4306
|
+
<!-- Generated Lists -->
|
|
4307
|
+
<!-- ############### -->
|
|
4308
|
+
|
|
4309
|
+
<!-- The Index -->
|
|
4310
|
+
|
|
4311
|
+
<!-- pretext-common.xsl collects, sorts, and groups the "idx" -->
|
|
4312
|
+
<!-- elements when it encounters "index-list"; this conversion -->
|
|
4313
|
+
<!-- supplies the presentation through the abstract "present-*" -->
|
|
4314
|
+
<!-- named templates below. A locator is the page number of the -->
|
|
4315
|
+
<!-- "idx" location (the anchors made in the default "idx" -->
|
|
4316
|
+
<!-- template), each a native XSL-FO page-number citation, so a -->
|
|
4317
|
+
<!-- complete back-of-the-book index emerges in a single pass: -->
|
|
4318
|
+
<!-- no makeindex , no second run. -->
|
|
4319
|
+
|
|
4320
|
+
<!-- "index-list" is implemented in common. -->
|
|
4321
|
+
|
|
4322
|
+
|
|
4323
|
+
<!-- the body of the index passes through -->
|
|
4324
|
+
<xsl:template name="present-index">
|
|
4325
|
+
<xsl:param name="content"/>
|
|
4326
|
+
|
|
4327
|
+
<xsl:copy-of select="$content"/>
|
|
4328
|
+
</xsl:template>
|
|
4329
|
+
|
|
4330
|
+
<!-- a vertical gap separates letter groups, in the manner -->
|
|
4331
|
+
<!-- of the Chicago Manual of Style (and LaTeX defaults) -->
|
|
4332
|
+
<xsl:template name="present-letter-group">
|
|
4333
|
+
<xsl:param name="the-index-list"/>
|
|
4334
|
+
<xsl:param name="letter-group"/>
|
|
4335
|
+
<xsl:param name="current-letter"/>
|
|
4336
|
+
<xsl:param name="content"/>
|
|
4337
|
+
|
|
4338
|
+
<fo:block space-after="1em">
|
|
4339
|
+
<xsl:copy-of select="$content"/>
|
|
4340
|
+
</fo:block>
|
|
4341
|
+
</xsl:template>
|
|
4342
|
+
|
|
4343
|
+
<!-- One index entry: the heading at its level (12pt of indentation -->
|
|
4344
|
+
<!-- per level), wrapped lines hanging a step further, and then the -->
|
|
4345
|
+
<!-- locators, when this heading is the deepest of its entry. -->
|
|
4346
|
+
<xsl:template name="present-index-heading">
|
|
4347
|
+
<xsl:param name="the-index-list"/>
|
|
4348
|
+
<xsl:param name="heading-group"/>
|
|
4349
|
+
<xsl:param name="b-write-locators"/>
|
|
4350
|
+
<xsl:param name="heading-level"/>
|
|
4351
|
+
<xsl:param name="content"/>
|
|
4352
|
+
|
|
4353
|
+
<fo:block start-indent="{12 * $heading-level}pt" text-indent="-12pt">
|
|
4354
|
+
<xsl:copy-of select="$content"/>
|
|
4355
|
+
<xsl:if test="$b-write-locators">
|
|
4356
|
+
<xsl:call-template name="locator-list">
|
|
4357
|
+
<xsl:with-param name="the-index-list" select="$the-index-list"/>
|
|
4358
|
+
<xsl:with-param name="heading-group" select="$heading-group"/>
|
|
4359
|
+
<xsl:with-param name="cross-reference-separator" select="', '"/>
|
|
4360
|
+
</xsl:call-template>
|
|
4361
|
+
</xsl:if>
|
|
4362
|
+
</fo:block>
|
|
4363
|
+
</xsl:template>
|
|
4364
|
+
|
|
4365
|
+
<!-- the pieces of a locator: processed content suffices -->
|
|
4366
|
+
<xsl:template name="present-index-locator">
|
|
4367
|
+
<xsl:param name="content"/>
|
|
4368
|
+
|
|
4369
|
+
<xsl:copy-of select="$content"/>
|
|
4370
|
+
</xsl:template>
|
|
4371
|
+
|
|
4372
|
+
<xsl:template name="present-index-see">
|
|
4373
|
+
<xsl:param name="content"/>
|
|
4374
|
+
|
|
4375
|
+
<xsl:copy-of select="$content"/>
|
|
4376
|
+
</xsl:template>
|
|
4377
|
+
|
|
4378
|
+
<xsl:template name="present-index-see-also">
|
|
4379
|
+
<xsl:param name="content"/>
|
|
4380
|
+
|
|
4381
|
+
<xsl:copy-of select="$content"/>
|
|
4382
|
+
</xsl:template>
|
|
4383
|
+
|
|
4384
|
+
<xsl:template name="present-index-italics">
|
|
4385
|
+
<xsl:param name="content"/>
|
|
4386
|
+
|
|
4387
|
+
<fo:inline font-style="italic">
|
|
4388
|
+
<xsl:copy-of select="$content"/>
|
|
4389
|
+
</fo:inline>
|
|
4390
|
+
</xsl:template>
|
|
4391
|
+
|
|
4392
|
+
<!-- One locator: the page number where the "idx" element sits, -->
|
|
4393
|
+
<!-- which doubles as a live link in an electronic PDF. -->
|
|
4394
|
+
<xsl:template match="index-list" mode="index-enclosure">
|
|
4395
|
+
<xsl:param name="enclosure"/>
|
|
4396
|
+
|
|
4397
|
+
<xsl:variable name="the-id">
|
|
4398
|
+
<xsl:apply-templates select="$enclosure" mode="unique-id"/>
|
|
4399
|
+
</xsl:variable>
|
|
4400
|
+
<fo:basic-link internal-destination="{$the-id}" fox:alt-text="page of this index entry">
|
|
4401
|
+
<xsl:call-template name="link-attributes"/>
|
|
4402
|
+
<fo:page-number-citation ref-id="{$the-id}"/>
|
|
4403
|
+
</fo:basic-link>
|
|
4404
|
+
</xsl:template>
|
|
4405
|
+
|
|
4406
|
+
<!-- The Notation List -->
|
|
4407
|
+
|
|
4408
|
+
<!-- pretext-common.xsl walks every "notation" of the document, in -->
|
|
4409
|
+
<!-- order, when it meets "notation-list"; here, a table of the -->
|
|
4410
|
+
<!-- sample usage (as mathematics), the narrative description, and -->
|
|
4411
|
+
<!-- a cross-reference to the enclosing environment. -->
|
|
4412
|
+
|
|
4413
|
+
<!-- "notation-list" is implemented in common. -->
|
|
4414
|
+
|
|
4415
|
+
|
|
4416
|
+
<xsl:template name="present-notation-list">
|
|
4417
|
+
<xsl:param name="content"/>
|
|
4418
|
+
|
|
4419
|
+
<fo:table table-layout="fixed" width="100%" space-before="1em" space-after="1em">
|
|
4420
|
+
<fo:table-column column-width="proportional-column-width(2)"/>
|
|
4421
|
+
<fo:table-column column-width="proportional-column-width(4)"/>
|
|
4422
|
+
<fo:table-column column-width="proportional-column-width(2)"/>
|
|
4423
|
+
<fo:table-header>
|
|
4424
|
+
<fo:table-row>
|
|
4425
|
+
<fo:table-cell padding="2pt" border-bottom-style="solid" border-bottom-width="0.7pt">
|
|
4426
|
+
<fo:block font-weight="bold">
|
|
4427
|
+
<xsl:apply-templates select="." mode="type-name">
|
|
4428
|
+
<xsl:with-param name="string-id" select="'symbol'"/>
|
|
4429
|
+
</xsl:apply-templates>
|
|
4430
|
+
</fo:block>
|
|
4431
|
+
</fo:table-cell>
|
|
4432
|
+
<fo:table-cell padding="2pt" border-bottom-style="solid" border-bottom-width="0.7pt">
|
|
4433
|
+
<fo:block font-weight="bold">
|
|
4434
|
+
<xsl:apply-templates select="." mode="type-name">
|
|
4435
|
+
<xsl:with-param name="string-id" select="'description'"/>
|
|
4436
|
+
</xsl:apply-templates>
|
|
4437
|
+
</fo:block>
|
|
4438
|
+
</fo:table-cell>
|
|
4439
|
+
<fo:table-cell padding="2pt" border-bottom-style="solid" border-bottom-width="0.7pt">
|
|
4440
|
+
<fo:block font-weight="bold">
|
|
4441
|
+
<xsl:apply-templates select="." mode="type-name">
|
|
4442
|
+
<xsl:with-param name="string-id" select="'location'"/>
|
|
4443
|
+
</xsl:apply-templates>
|
|
4444
|
+
</fo:block>
|
|
4445
|
+
</fo:table-cell>
|
|
4446
|
+
</fo:table-row>
|
|
4447
|
+
</fo:table-header>
|
|
4448
|
+
<fo:table-body>
|
|
4449
|
+
<xsl:copy-of select="$content"/>
|
|
4450
|
+
</fo:table-body>
|
|
4451
|
+
</fo:table>
|
|
4452
|
+
</xsl:template>
|
|
4453
|
+
|
|
4454
|
+
<!-- exactly one "m" of the usage; the description duplicated; -->
|
|
4455
|
+
<!-- a cross-reference to the enclosure, with its page number -->
|
|
4456
|
+
<!-- in print (automatic, from "xref-link") -->
|
|
4457
|
+
<xsl:template match="notation" mode="present-notation-item">
|
|
4458
|
+
<fo:table-row>
|
|
4459
|
+
<fo:table-cell padding="2pt" display-align="before">
|
|
4460
|
+
<fo:block>
|
|
4461
|
+
<xsl:apply-templates select="usage/m[1]"/>
|
|
4462
|
+
</fo:block>
|
|
4463
|
+
</fo:table-cell>
|
|
4464
|
+
<fo:table-cell padding="2pt" display-align="before">
|
|
4465
|
+
<fo:block>
|
|
4466
|
+
<xsl:apply-templates select="description/node()"/>
|
|
4467
|
+
</fo:block>
|
|
4468
|
+
</fo:table-cell>
|
|
4469
|
+
<fo:table-cell padding="2pt" display-align="before">
|
|
4470
|
+
<fo:block>
|
|
4471
|
+
<xsl:apply-templates select="." mode="enclosure-xref"/>
|
|
4472
|
+
</fo:block>
|
|
4473
|
+
</fo:table-cell>
|
|
4474
|
+
</fo:table-row>
|
|
4475
|
+
</xsl:template>
|
|
4476
|
+
|
|
4477
|
+
<!-- Climb the tree to the first enclosure that is a block or is -->
|
|
4478
|
+
<!-- structural, and make a cross-reference to it; recursion -->
|
|
4479
|
+
<!-- always halts, since the document root is structural. -->
|
|
4480
|
+
<xsl:template match="*" mode="enclosure-xref">
|
|
4481
|
+
<xsl:variable name="structural">
|
|
4482
|
+
<xsl:apply-templates select="." mode="is-structural"/>
|
|
4483
|
+
</xsl:variable>
|
|
4484
|
+
<xsl:variable name="block">
|
|
4485
|
+
<xsl:apply-templates select="." mode="is-block"/>
|
|
4486
|
+
</xsl:variable>
|
|
4487
|
+
<xsl:choose>
|
|
4488
|
+
<xsl:when test="($structural = 'true') or ($block = 'true')">
|
|
4489
|
+
<xsl:apply-templates select="." mode="xref-link">
|
|
4490
|
+
<xsl:with-param name="target" select="."/>
|
|
4491
|
+
<xsl:with-param name="origin" select="'notation'"/>
|
|
4492
|
+
<xsl:with-param name="content">
|
|
4493
|
+
<xsl:apply-templates select="." mode="type-name"/>
|
|
4494
|
+
<xsl:variable name="enclosure-number">
|
|
4495
|
+
<xsl:apply-templates select="." mode="number"/>
|
|
4496
|
+
</xsl:variable>
|
|
4497
|
+
<xsl:if test="not($enclosure-number = '')">
|
|
4498
|
+
<xsl:text> </xsl:text>
|
|
4499
|
+
<xsl:value-of select="$enclosure-number"/>
|
|
4500
|
+
</xsl:if>
|
|
4501
|
+
</xsl:with-param>
|
|
4502
|
+
</xsl:apply-templates>
|
|
4503
|
+
</xsl:when>
|
|
4504
|
+
<xsl:otherwise>
|
|
4505
|
+
<xsl:apply-templates select="parent::*" mode="enclosure-xref"/>
|
|
4506
|
+
</xsl:otherwise>
|
|
4507
|
+
</xsl:choose>
|
|
4508
|
+
</xsl:template>
|
|
4509
|
+
|
|
4510
|
+
<!-- Lists of Blocks ("list-of") -->
|
|
4511
|
+
|
|
4512
|
+
<!-- pretext-common.xsl ranges over a scope of the document when -->
|
|
4513
|
+
<!-- it meets a "list-of", emitting division headings and the -->
|
|
4514
|
+
<!-- elements the author requested; here, each element is one -->
|
|
4515
|
+
<!-- line, a live cross-reference followed by any title. -->
|
|
4516
|
+
|
|
4517
|
+
<!-- "list-of" is implemented in common. -->
|
|
4518
|
+
|
|
4519
|
+
|
|
4520
|
+
<!-- no surrounding infrastructure necessary -->
|
|
4521
|
+
<xsl:template name="list-of-begin"/>
|
|
4522
|
+
<xsl:template name="list-of-end"/>
|
|
4523
|
+
|
|
4524
|
+
<!-- Subdivision headings within a "list-of": type-name, number, title. -->
|
|
4525
|
+
<xsl:template match="*" mode="list-of-heading">
|
|
4526
|
+
<fo:block font-weight="bold"
|
|
4527
|
+
font-size="120%"
|
|
4528
|
+
space-before="1.5em"
|
|
4529
|
+
space-after="0.75em"
|
|
4530
|
+
keep-with-next.within-page="always">
|
|
4531
|
+
<xsl:apply-templates select="." mode="type-name"/>
|
|
4532
|
+
<xsl:variable name="the-number">
|
|
4533
|
+
<xsl:apply-templates select="." mode="number"/>
|
|
4534
|
+
</xsl:variable>
|
|
4535
|
+
<xsl:if test="not($the-number = '')">
|
|
4536
|
+
<xsl:text> </xsl:text>
|
|
4537
|
+
<xsl:value-of select="$the-number"/>
|
|
4538
|
+
</xsl:if>
|
|
4539
|
+
<xsl:variable name="the-title">
|
|
4540
|
+
<xsl:apply-templates select="." mode="title-simple"/>
|
|
4541
|
+
</xsl:variable>
|
|
4542
|
+
<xsl:if test="not(normalize-space($the-title) = '')">
|
|
4543
|
+
<xsl:text> </xsl:text>
|
|
4544
|
+
<xsl:value-of select="normalize-space($the-title)"/>
|
|
4545
|
+
</xsl:if>
|
|
4546
|
+
</fo:block>
|
|
4547
|
+
</xsl:template>
|
|
4548
|
+
|
|
4549
|
+
<xsl:template match="*" mode="list-of-element">
|
|
4550
|
+
<fo:block>
|
|
4551
|
+
<xsl:apply-templates select="." mode="xref-link">
|
|
4552
|
+
<xsl:with-param name="target" select="."/>
|
|
4553
|
+
<xsl:with-param name="origin" select="'list-of'"/>
|
|
4554
|
+
<xsl:with-param name="content">
|
|
4555
|
+
<xsl:apply-templates select="." mode="type-name"/>
|
|
4556
|
+
<xsl:text> </xsl:text>
|
|
4557
|
+
<xsl:apply-templates select="." mode="number"/>
|
|
4558
|
+
</xsl:with-param>
|
|
4559
|
+
</xsl:apply-templates>
|
|
4560
|
+
<xsl:if test="title">
|
|
4561
|
+
<xsl:text> </xsl:text>
|
|
4562
|
+
<xsl:apply-templates select="." mode="title-xref"/>
|
|
4563
|
+
</xsl:if>
|
|
4564
|
+
</fo:block>
|
|
4565
|
+
</xsl:template>
|
|
4566
|
+
|
|
4567
|
+
<!-- ################ -->
|
|
4568
|
+
<!-- Coverage Harness -->
|
|
4569
|
+
<!-- ################ -->
|
|
4570
|
+
|
|
4571
|
+
<!-- *Every* element needs an implementation, or it lands here and is -->
|
|
4572
|
+
<!-- reported as unimplemented. Elements that common.xsl handles are -->
|
|
4573
|
+
<!-- named in the exclusion list below, so they are not matched here -->
|
|
4574
|
+
<!-- but fall through to common, replacing the per-element -->
|
|
4575
|
+
<!-- "apply-imports" shims. Emptied, the template can go. We recurse -->
|
|
4576
|
+
<!-- through element children, and drop interior text, so the output -->
|
|
4577
|
+
<!-- is always legal XSL-FO. Survey what remains to implement, as a -->
|
|
4578
|
+
<!-- counted summary, with something like -->
|
|
4579
|
+
<!-- pretext/pretext -v ... 2>&1 | grep 'PTX:FO-TODO' \ -->
|
|
4580
|
+
<!-- | sort | uniq -c | sort -rn -->
|
|
4581
|
+
<xsl:template priority="-0.5" match="*[not(
|
|
4582
|
+
self::pretext or self::prefigure[not(node())] or self::webwork[not(* or @copy or @source)] or
|
|
4583
|
+
self::xetex or self::xelatex or
|
|
4584
|
+
self::ad or self::am or self::bc or self::ca or self::eg or self::etal or self::etc or self::ie or self::nb or self::pm or self::ps or self::vs or self::viz or
|
|
4585
|
+
self::nbsp or self::ndash or self::mdash or self::lsq or self::rsq or self::lq or self::rq or self::ldblbracket or self::rdblbracket or self::langle or self::rangle or self::ellipsis or self::midpoint or self::swungdash or self::permille or self::pilcrow or self::section-mark or self::minus or self::times or self::solidus or self::obelus or self::plusminus or self::copyright or self::phonomark or self::copyleft or self::registered or self::trademark or self::servicemark or self::degree or self::prime or self::dblprime or
|
|
4586
|
+
self::q or self::sq or self::dblbrackets or self::angles or
|
|
4587
|
+
self::c or self::cline or self::tag or self::tage or self::attr or self::today or self::timeofday or self::pi:localize or
|
|
4588
|
+
self::xref or self::index-list or self::notation-list or self::list-of)]">
|
|
4589
|
+
<xsl:message>PTX:FO-TODO: <xsl:value-of select="local-name()"/> (child of "<xsl:value-of select="local-name(parent::*)"/>")</xsl:message>
|
|
4590
|
+
<xsl:apply-templates select="*"/>
|
|
4591
|
+
</xsl:template>
|
|
4592
|
+
|
|
4593
|
+
</xsl:stylesheet>
|