1
<?xml version='1.0' encoding='utf-8'?>
2
3
<!-- XHTML-to-Latex converter by Fletcher Penney
4
specifically designed for use with MultiMarkdown created XHTML
5
6
MultiMarkdown Version 2.0.b6
7
8
$Id: xhtml2latex.xslt 517 2008-09-12 19:37:52Z fletcher $
9
-->
10
11
<!--
12
/=======================================================================
13
| Minor modifications by Timothy Vismor
14
| May 2010
15
|=======================================================================
16
|
17
| This file generates an article (one-sided) with a table of contents,
18
| a list of figures, and a list of tables,
19
|
20
| Modifications are intended to make output more compatible with
21
| the static page maintenance workflow at vismor.com. Also minor
22
| adjustments to the appearance of the formatted document's title
23
| page, table handling, and equation handling are implemented.
24
|
25
| For a more complete understanding of the changes, diff this file
26
| against xhtml2latex.xslt in the standard MMD distribution. You
27
| can also search this file for "vismor" to find modifed areas.
28
\=======================================================================
29
-->
30
31
<!--
32
# Copyright (C) 2005-2008 Fletcher T. Penney <fletcher@fletcherpenney.net>
33
#
34
# This program is free software; you can redistribute it and/or modify
35
# it under the terms of the GNU General Public License as published by
36
# the Free Software Foundation; either version 2 of the License, or
37
# (at your option) any later version.
38
#
39
# This program is distributed in the hope that it will be useful,
40
# but WITHOUT ANY WARRANTY; without even the implied warranty of
41
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
42
# GNU General Public License for more details.
43
#
44
# You should have received a copy of the GNU General Public License
45
# along with this program; if not, write to the
46
# Free Software Foundation, Inc.
47
# 59 Temple Place, Suite 330
48
# Boston, MA 02111-1307 USA
49
-->
50
51
52
53
<xsl:stylesheet
54
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
55
xmlns:m="http://www.w3.org/1998/Math/MathML"
56
xmlns:html="http://www.w3.org/1999/xhtml"
57
version="1.0">
58
59
<xsl:import href="../MultiMarkdownXSLTMathML/mmltex.xsl"/>
60
<xsl:import href="clean-text.xslt"/>
61
62
<!-- ===== vismor ===== -->
63
<xsl:output method='text' encoding='utf-8' omit-xml-declaration = 'yes'/>
64
<!-- ================== -->
65
66
<xsl:strip-space elements="*" />
67
68
<xsl:variable name="newline">
69
<xsl:text>
70
</xsl:text>
71
</xsl:variable>
72
73
<xsl:param name="footnoteId"/>
74
75
<xsl:decimal-format name="string" NaN="1"/>
76
77
<xsl:template match="*[local-name() = 'title']">
78
<xsl:text>\def\mytitle{</xsl:text>
79
<xsl:call-template name="clean-text">
80
<xsl:with-param name="source">
81
<xsl:value-of select="."/>
82
</xsl:with-param>
83
</xsl:call-template>
84
<xsl:text>}
85
</xsl:text>
86
</xsl:template>
87
88
89
<xsl:template match="html:meta">
90
<xsl:choose>
91
<xsl:when test="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
92
'abcdefghijklmnopqrstuvwxyz') = 'author'">
93
<xsl:text>\def\myauthor{</xsl:text>
94
<xsl:call-template name="clean-text">
95
<xsl:with-param name="source">
96
<xsl:value-of select="@content"/>
97
</xsl:with-param>
98
</xsl:call-template>
99
<xsl:text>}
100
</xsl:text>
101
</xsl:when>
102
<xsl:when test="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
103
'abcdefghijklmnopqrstuvwxyz') = 'latexauthor'">
104
<xsl:text>\def\latexauthor{</xsl:text>
105
<xsl:value-of select="@content"/>
106
<xsl:text>}
107
</xsl:text>
108
</xsl:when>
109
<xsl:when test="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
110
'abcdefghijklmnopqrstuvwxyz') = 'date'">
111
<xsl:text>\date{</xsl:text>
112
<xsl:call-template name="clean-text">
113
<xsl:with-param name="source">
114
<xsl:value-of select="@content"/>
115
</xsl:with-param>
116
</xsl:call-template>
117
<xsl:text>}
118
\def\mydate{</xsl:text>
119
<xsl:call-template name="clean-text">
120
<xsl:with-param name="source">
121
<xsl:value-of select="@content"/>
122
</xsl:with-param>
123
</xsl:call-template>
124
<xsl:text>}
125
</xsl:text>
126
</xsl:when>
127
<xsl:when test="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
128
'abcdefghijklmnopqrstuvwxyz') = 'affiliation'">
129
<xsl:text>\def\affiliation{</xsl:text>
130
<xsl:call-template name="replace-substring">
131
<!-- put line breaks in -->
132
<xsl:with-param name="original">
133
<xsl:call-template name="clean-text">
134
<xsl:with-param name="source">
135
<xsl:value-of select="@content"/>
136
</xsl:with-param>
137
</xsl:call-template>
138
</xsl:with-param>
139
<xsl:with-param name="substring">
140
<xsl:text> </xsl:text>
141
</xsl:with-param>
142
<xsl:with-param name="replacement">
143
<xsl:text> \\ </xsl:text>
144
</xsl:with-param>
145
</xsl:call-template>
146
<xsl:text>}
147
</xsl:text>
148
</xsl:when>
149
<xsl:when test="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
150
'abcdefghijklmnopqrstuvwxyz') = 'revision'">
151
<xsl:text>\def\revision{Revision: </xsl:text>
152
<xsl:call-template name="clean-text">
153
<xsl:with-param name="source">
154
<xsl:value-of select="@content"/>
155
</xsl:with-param>
156
</xsl:call-template>
157
<xsl:text>}
158
</xsl:text>
159
</xsl:when>
160
<xsl:when test="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
161
'abcdefghijklmnopqrstuvwxyz') = 'email'">
162
<xsl:text>\def\email{ \href{mailto:</xsl:text>
163
<xsl:call-template name="replace-substring">
164
<!-- put line breaks in -->
165
<xsl:with-param name="original">
166
<xsl:call-template name="clean-text">
167
<xsl:with-param name="source">
168
<xsl:value-of select="@content"/>
169
</xsl:with-param>
170
</xsl:call-template>
171
</xsl:with-param>
172
<xsl:with-param name="substring">
173
<xsl:text> </xsl:text>
174
</xsl:with-param>
175
<xsl:with-param name="replacement">
176
<xsl:text> \\ </xsl:text>
177
</xsl:with-param>
178
</xsl:call-template>
179
<xsl:text>}{</xsl:text>
180
<xsl:call-template name="replace-substring">
181
<!-- put line breaks in -->
182
<xsl:with-param name="original">
183
<xsl:call-template name="clean-text">
184
<xsl:with-param name="source">
185
<xsl:value-of select="@content"/>
186
</xsl:with-param>
187
</xsl:call-template>
188
</xsl:with-param>
189
<xsl:with-param name="substring">
190
<xsl:text> </xsl:text>
191
</xsl:with-param>
192
<xsl:with-param name="replacement">
193
<xsl:text> \\ </xsl:text>
194
</xsl:with-param>
195
</xsl:call-template>
196
<xsl:text>}}
197
</xsl:text>
198
</xsl:when>
199
<xsl:when test="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
200
'abcdefghijklmnopqrstuvwxyz') = 'web'">
201
<xsl:text>\def\web{\href{</xsl:text>
202
<xsl:if test="not(starts-with(@content,'http:'))">
203
<xsl:text>http://</xsl:text>
204
</xsl:if>
205
<xsl:call-template name="replace-substring">
206
<!-- put line breaks in -->
207
<xsl:with-param name="original">
208
<xsl:call-template name="clean-text">
209
<xsl:with-param name="source">
210
<xsl:value-of select="@content"/>
211
</xsl:with-param>
212
</xsl:call-template>
213
</xsl:with-param>
214
<xsl:with-param name="substring">
215
<xsl:text> </xsl:text>
216
</xsl:with-param>
217
<xsl:with-param name="replacement">
218
<xsl:text> \\ </xsl:text>
219
</xsl:with-param>
220
</xsl:call-template>
221
<xsl:text>}{</xsl:text>
222
<xsl:call-template name="replace-substring">
223
<!-- put line breaks in -->
224
<xsl:with-param name="original">
225
<xsl:call-template name="clean-text">
226
<xsl:with-param name="source">
227
<xsl:value-of select="@content"/>
228
</xsl:with-param>
229
</xsl:call-template>
230
</xsl:with-param>
231
<xsl:with-param name="substring">
232
<xsl:text> </xsl:text>
233
</xsl:with-param>
234
<xsl:with-param name="replacement">
235
<xsl:text> \\ </xsl:text>
236
</xsl:with-param>
237
</xsl:call-template>
238
<xsl:text>}}
239
</xsl:text>
240
</xsl:when>
241
<xsl:when test="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
242
'abcdefghijklmnopqrstuvwxyz') = 'keywords'">
243
<xsl:text>\def\mykeywords{</xsl:text>
244
<xsl:call-template name="replace-substring">
245
<xsl:with-param name="original">
246
<xsl:value-of select="@content"/>
247
</xsl:with-param>
248
<xsl:with-param name="substring">
249
<xsl:text>,,</xsl:text>
250
</xsl:with-param>
251
<xsl:with-param name="replacement">
252
<xsl:text>,</xsl:text>
253
</xsl:with-param>
254
</xsl:call-template>
255
<xsl:text>}
256
</xsl:text>
257
</xsl:when>
258
<xsl:when test="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
259
'abcdefghijklmnopqrstuvwxyz') = 'xmp'">
260
<xsl:text>\usepackage{xmpincl}
261
\includexmp{</xsl:text>
262
<xsl:call-template name="clean-text">
263
<xsl:with-param name="source">
264
<xsl:value-of select="@content"/>
265
</xsl:with-param>
266
</xsl:call-template>
267
<xsl:text>}
268
</xsl:text>
269
</xsl:when>
270
<xsl:when test="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
271
'abcdefghijklmnopqrstuvwxyz') = 'bibtex'">
272
<xsl:text>\def\bibliocommand{\bibliography{</xsl:text>
273
<xsl:call-template name="clean-text">
274
<xsl:with-param name="source">
275
<xsl:value-of select="@content"/>
276
</xsl:with-param>
277
</xsl:call-template>
278
<xsl:text>}}
279
</xsl:text>
280
</xsl:when>
281
<xsl:when test="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
282
'abcdefghijklmnopqrstuvwxyz') = 'bibliographystyle'">
283
<xsl:text>\def\mybibliostyle{</xsl:text>
284
<xsl:call-template name="clean-text">
285
<xsl:with-param name="source">
286
<xsl:value-of select="@content"/>
287
</xsl:with-param>
288
</xsl:call-template>
289
<xsl:text>}
290
</xsl:text>
291
</xsl:when>
292
<xsl:when test="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
293
'abcdefghijklmnopqrstuvwxyz') = 'bibliographytitle'">
294
<xsl:call-template name="rename-bibliography">
295
<xsl:with-param name="source">
296
<xsl:value-of select="@content"/>
297
</xsl:with-param>
298
</xsl:call-template>
299
</xsl:when>
300
<xsl:when test="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
301
'abcdefghijklmnopqrstuvwxyz') = 'chapterstyle'">
302
<xsl:text>\def\mychapterstyle{</xsl:text>
303
<xsl:call-template name="clean-text">
304
<xsl:with-param name="source">
305
<xsl:value-of select="@content"/>
306
</xsl:with-param>
307
</xsl:call-template>
308
<xsl:text>}
309
</xsl:text>
310
</xsl:when>
311
<xsl:when test="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
312
'abcdefghijklmnopqrstuvwxyz') = 'pagestyle'">
313
<xsl:text>\def\mypagestyle{</xsl:text>
314
<xsl:call-template name="clean-text">
315
<xsl:with-param name="source">
316
<xsl:value-of select="@content"/>
317
</xsl:with-param>
318
</xsl:call-template>
319
<xsl:text>}
320
</xsl:text>
321
</xsl:when>
322
<xsl:when test="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
323
'abcdefghijklmnopqrstuvwxyz') = 'copyright'">
324
<xsl:text>\def\mycopyright{</xsl:text>
325
<xsl:call-template name="replace-substring">
326
<!-- put line breaks in -->
327
<xsl:with-param name="original">
328
<xsl:call-template name="clean-text">
329
<xsl:with-param name="source">
330
<xsl:value-of select="@content"/>
331
</xsl:with-param>
332
</xsl:call-template>
333
</xsl:with-param>
334
<xsl:with-param name="substring">
335
<xsl:text> </xsl:text>
336
</xsl:with-param>
337
<xsl:with-param name="replacement">
338
<xsl:text> \\ </xsl:text>
339
</xsl:with-param>
340
</xsl:call-template>
341
<xsl:text>}
342
</xsl:text>
343
</xsl:when>
344
<xsl:when test="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
345
'abcdefghijklmnopqrstuvwxyz') = 'closing'">
346
<xsl:text>\def\myclosing{</xsl:text>
347
<xsl:call-template name="replace-substring">
348
<!-- put line breaks in -->
349
<xsl:with-param name="original">
350
<xsl:call-template name="clean-text">
351
<xsl:with-param name="source">
352
<xsl:value-of select="@content"/>
353
</xsl:with-param>
354
</xsl:call-template>
355
</xsl:with-param>
356
<xsl:with-param name="substring">
357
<xsl:text> </xsl:text>
358
</xsl:with-param>
359
<xsl:with-param name="replacement">
360
<xsl:text> \\ </xsl:text>
361
</xsl:with-param>
362
</xsl:call-template>
363
<xsl:text>}
364
</xsl:text>
365
</xsl:when>
366
<xsl:otherwise>
367
<xsl:text>\def\</xsl:text>
368
<xsl:value-of select="translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
369
'abcdefghijklmnopqrstuvwxyz')"/>
370
<xsl:text>{</xsl:text>
371
<xsl:call-template name="replace-substring">
372
<!-- put line breaks in -->
373
<xsl:with-param name="original">
374
<xsl:call-template name="clean-text">
375
<xsl:with-param name="source">
376
<xsl:value-of select="@content"/>
377
</xsl:with-param>
378
</xsl:call-template>
379
</xsl:with-param>
380
<xsl:with-param name="substring">
381
<xsl:text> </xsl:text>
382
</xsl:with-param>
383
<xsl:with-param name="replacement">
384
<xsl:text> \\ </xsl:text>
385
</xsl:with-param>
386
</xsl:call-template>
387
<xsl:text>}
388
</xsl:text>
389
</xsl:otherwise>
390
</xsl:choose>
391
</xsl:template>
392
393
<xsl:template match="html:body">
394
<xsl:apply-templates select="*|comment()"/>
395
<!-- <xsl:apply-templates select="*"/> Use this version to ignore text within XHTML comments-->
396
</xsl:template>
397
398
<xsl:template match="html:head">
399
<!-- Init Latex -->
400
<xsl:call-template name="latex-document-class"/>
401
<xsl:call-template name="latex-paper-size"/>
402
<xsl:call-template name="latex-header"/>
403
<xsl:apply-templates select="*"/>
404
<xsl:call-template name="latex-intro"/>
405
<xsl:call-template name="latex-title"/>
406
<xsl:call-template name="latex-copyright"/>
407
<xsl:call-template name="latex-begin-body"/>
408
</xsl:template>
409
410
<!-- ignore other information within the header
411
This will need to be expanded upon over time -->
412
413
<xsl:template match="html:head/html:style">
414
</xsl:template>
415
416
<xsl:template match="html:head/html:base">
417
</xsl:template>
418
419
<xsl:template match="html:head/html:link">
420
</xsl:template>
421
422
<xsl:template match="html:head/html:object">
423
</xsl:template>
424
425
<xsl:template match="html:head/html:script">
426
</xsl:template>
427
428
429
<xsl:template name="latex-title">
430
<!-- Set up title -->
431
<xsl:text>
432
433
% Title Page
434
435
\maketitle
436
<!-- ===== vismor ===== -->
437
\thispagestyle{empty}
438
<!-- ================== -->
439
</xsl:text>
440
</xsl:template>
441
442
<xsl:template name="latex-copyright">
443
<!-- Set up copyright -->
444
<xsl:text>% Copyright Page
445
<!-- ===== vismor ===== -->
446
\vfill
447
<!-- ================== -->
448
\ifx\mycopyright\undefined
449
\else
450
Copyright \textcopyright{} \mycopyright
451
\fi
452
<!-- ===== vismor ===== -->
453
\newpage
454
\tableofcontents
455
\listoffigures
456
\listoftables
457
\lstlistoflistings
458
\newpage
459
<!-- ================== -->
460
461
462
</xsl:text>
463
</xsl:template>
464
465
<xsl:template name="latex-begin-body">
466
<xsl:text>%
467
% Main Content
468
%
469
470
471
</xsl:text>
472
</xsl:template>
473
474
475
<xsl:template match="text()">
476
<xsl:call-template name="clean-text">
477
<xsl:with-param name="source">
478
<xsl:value-of select="."/>
479
</xsl:with-param>
480
</xsl:call-template>
481
</xsl:template>
482
483
<xsl:template match="m:*/text()">
484
<xsl:call-template name="replaceEntities">
485
<xsl:with-param name="content" select="normalize-space()"/>
486
</xsl:call-template>
487
</xsl:template>
488
489
<!-- Rename Bibliography -->
490
<xsl:template name="rename-bibliography">
491
<xsl:param name="source" />
492
<xsl:text>\renewcommand\refname{</xsl:text>
493
<xsl:value-of select="$source" />
494
<xsl:text>}
495
</xsl:text>
496
</xsl:template>
497
498
499
<!-- paragraphs -->
500
501
<xsl:template match="html:p">
502
<xsl:apply-templates select="node()"/>
503
<xsl:value-of select="$newline"/>
504
<xsl:value-of select="$newline"/>
505
<xsl:value-of select="$newline"/>
506
</xsl:template>
507
508
<!-- last paragraph in a blockquote doesn't need extra newline -->
509
<!-- needed for epigraph support -->
510
<xsl:template match="html:p[last()][parent::*[local-name() = 'blockquote']]">
511
<xsl:apply-templates select="node()"/>
512
<xsl:value-of select="$newline"/>
513
</xsl:template>
514
515
<!-- footnote li -->
516
<!-- print contents of the matching footnote -->
517
<xsl:template match="html:li" mode="footnote">
518
<xsl:param name="footnoteId"/>
519
<xsl:if test="parent::html:ol/parent::html:div/@class = 'footnotes'">
520
<xsl:if test="concat('#',@id) = $footnoteId">
521
<xsl:apply-templates select="node()"/>
522
</xsl:if>
523
</xsl:if>
524
</xsl:template>
525
526
<!-- last paragraph in footnote does not need trailing space -->
527
<xsl:template match="html:p[last()][parent::html:li[parent::html:ol[parent::html:div[@class='footnotes']]]]">
528
<xsl:apply-templates select="node()"/>
529
</xsl:template>
530
531
<!-- print contents of the matching footnote as a glossary entry-->
532
<xsl:template match="html:li" mode="glossary">
533
<xsl:param name="footnoteId"/>
534
<xsl:if test="parent::html:ol/parent::html:div/@class = 'footnotes'">
535
<xsl:if test="concat('#',@id) = $footnoteId">
536
<xsl:apply-templates select="html:span" mode="glossary"/>
537
<xsl:text>description=</xsl:text>
538
<xsl:apply-templates select="html:p" mode="glossary"/>
539
<xsl:text>}</xsl:text>
540
</xsl:if>
541
</xsl:if>
542
</xsl:template>
543
544
<xsl:template match="html:p" mode="glossary">
545
<xsl:apply-templates select="node()"/>
546
<xsl:if test="position()!= last()">
547
<xsl:text>\\
548
\\
549
</xsl:text>
550
</xsl:if>
551
</xsl:template>
552
553
<xsl:template match="html:p[last()]" mode="glossary">
554
<xsl:apply-templates select="node()"/>
555
</xsl:template>
556
557
<!-- use these when asked for -->
558
<xsl:template match="html:span[@class='glossary name']" mode="glossary">
559
<xsl:text>{name=</xsl:text>
560
<xsl:apply-templates select="node()"/>
561
<xsl:text>,</xsl:text>
562
</xsl:template>
563
564
<xsl:template match="html:span[@class='glossary sort']" mode="glossary">
565
<xsl:text>sort=</xsl:text>
566
<xsl:apply-templates select="node()"/>
567
<xsl:text>,</xsl:text>
568
</xsl:template>
569
570
<!-- otherwise, ignore them -->
571
<xsl:template match="html:span[@class='glossary name']">
572
</xsl:template>
573
574
<xsl:template match="html:span[@class='glossary sort']">
575
</xsl:template>
576
577
<!-- anchors -->
578
<xsl:template match="html:a[@href]">
579
<xsl:choose>
580
<!-- footnote (my addition)-->
581
<xsl:when test="@class = 'footnote'">
582
<xsl:text>\footnote{</xsl:text>
583
<xsl:apply-templates select="/html:html/html:body/html:div[@class]/html:ol/html:li[@id]" mode="footnote">
584
<xsl:with-param name="footnoteId" select="@href"/>
585
</xsl:apply-templates>
586
<xsl:text>}</xsl:text>
587
</xsl:when>
588
589
<xsl:when test="@class = 'footnote glossary'">
590
<xsl:text>\glossary</xsl:text>
591
<xsl:apply-templates select="/html:html/html:body/html:div[@class]/html:ol/html:li[@id]" mode="glossary">
592
<xsl:with-param name="footnoteId" select="@href"/>
593
</xsl:apply-templates>
594
<xsl:text></xsl:text>
595
</xsl:when>
596
597
<xsl:when test="@class = 'reversefootnote'">
598
</xsl:when>
599
600
<!-- if href is same as the anchor text, then use \href{}
601
but no footnote -->
602
<!-- let's try \url{} again for line break reasons -->
603
<xsl:when test="@href = .">
604
<xsl:text>\url{</xsl:text>
605
<xsl:call-template name="clean-text">
606
<xsl:with-param name="source">
607
<xsl:value-of select="@href"/>
608
</xsl:with-param>
609
</xsl:call-template>
610
<xsl:text>}</xsl:text>
611
</xsl:when>
612
613
<!-- if href is mailto, use \href{} -->
614
<xsl:when test="starts-with(@href,'mailto:')">
615
<xsl:text>\href{</xsl:text>
616
<xsl:value-of select="@href"/>
617
<xsl:text>}{</xsl:text>
618
<xsl:call-template name="clean-text">
619
<xsl:with-param name="source">
620
<xsl:value-of select="substring-after(@href,'mailto:')"/>
621
</xsl:with-param>
622
</xsl:call-template>
623
<xsl:text>}</xsl:text>
624
</xsl:when>
625
626
<!-- if href is local anchor, use autoref -->
627
<xsl:when test="starts-with(@href,'#')">
628
<xsl:choose>
629
<xsl:when test=". = ''">
630
<xsl:text>\autoref{</xsl:text>
631
<xsl:value-of select="substring-after(@href,'#')"/>
632
<xsl:text>}</xsl:text>
633
</xsl:when>
634
<xsl:otherwise>
635
<xsl:value-of select="."/>
636
<xsl:text> (\autoref{</xsl:text>
637
<xsl:value-of select="substring-after(@href,'#')"/>
638
<xsl:text>})</xsl:text>
639
</xsl:otherwise>
640
</xsl:choose>
641
</xsl:when>
642
643
<!-- otherwise, implement an href and put href in footnote
644
for printed version -->
645
<xsl:otherwise>
646
<xsl:text>\href{</xsl:text>
647
<xsl:value-of select="@href"/>
648
<xsl:text>}{</xsl:text>
649
<xsl:call-template name="clean-text">
650
<xsl:with-param name="source">
651
<xsl:value-of select="."/>
652
</xsl:with-param>
653
</xsl:call-template>
654
<xsl:text>}\footnote{\href{</xsl:text>
655
<xsl:value-of select="@href"/>
656
<xsl:text>}{</xsl:text>
657
<xsl:call-template name="clean-text">
658
<xsl:with-param name="source">
659
<xsl:value-of select="@href"/>
660
</xsl:with-param>
661
</xsl:call-template>
662
<xsl:text>}}</xsl:text>
663
</xsl:otherwise>
664
</xsl:choose>
665
</xsl:template>
666
667
<!-- ordered list -->
668
<xsl:template match="html:ol">
669
<xsl:text>\begin{enumerate}</xsl:text>
670
<xsl:value-of select="$newline"/>
671
<xsl:value-of select="$newline"/>
672
<xsl:apply-templates select="*"/>
673
<xsl:text>\end{enumerate}</xsl:text>
674
<xsl:value-of select="$newline"/>
675
<xsl:value-of select="$newline"/>
676
</xsl:template>
677
678
<!-- unordered list -->
679
<xsl:template match="html:ul">
680
<xsl:text>\begin{itemize}</xsl:text>
681
<xsl:value-of select="$newline"/>
682
<xsl:value-of select="$newline"/>
683
<xsl:apply-templates select="*"/>
684
<xsl:text>\end{itemize}</xsl:text>
685
<xsl:value-of select="$newline"/>
686
<xsl:value-of select="$newline"/>
687
</xsl:template>
688
689
<!-- list item -->
690
<xsl:template match="html:li">
691
<xsl:text>
692
\item </xsl:text>
693
<xsl:apply-templates select="node()"/>
694
<xsl:value-of select="$newline"/>
695
</xsl:template>
696
697
<!-- definition list - fake it for compatibility with XHTML version -->
698
<xsl:template match="html:dl">
699
<xsl:apply-templates select="node()"/>
700
<xsl:text>
701
702
</xsl:text>
703
</xsl:template>
704
705
<xsl:template match="html:dt">
706
<xsl:text>\noindent\textbf{</xsl:text>
707
<xsl:apply-templates select="node()"/>
708
<xsl:text>}
709
</xsl:text>
710
</xsl:template>
711
712
<xsl:template match="html:dt[following-sibling::*[1][local-name() = 'dt']]">
713
<xsl:text>\noindent\textbf{</xsl:text>
714
<xsl:apply-templates select="node()"/>
715
<xsl:text>} \\
716
</xsl:text>
717
</xsl:template>
718
719
<xsl:template match="html:dd">
720
<xsl:text>\begin{quotation}
721
</xsl:text>
722
<xsl:apply-templates select="node()"/>
723
<xsl:text>\end{quotation}
724
</xsl:text>
725
</xsl:template>
726
727
<!-- code span -->
728
<xsl:template match="html:code">
729
<xsl:text>\texttt{</xsl:text>
730
<xsl:apply-templates select="node()"/>
731
<xsl:text>}</xsl:text>
732
</xsl:template>
733
734
<!-- line ending -->
735
<xsl:template match="html:br">
736
<xsl:text>\\</xsl:text>
737
</xsl:template>
738
739
<!-- blockquote -->
740
<xsl:template match="html:blockquote">
741
<xsl:text>\begin{quotation}
742
</xsl:text>
743
<xsl:apply-templates select="node()"/>
744
<xsl:text>\end{quotation}
745
746
</xsl:text>
747
</xsl:template>
748
749
<!-- emphasis -->
750
<xsl:template match="html:em">
751
<xsl:text>{\itshape </xsl:text>
752
<xsl:apply-templates select="node()"/>
753
<xsl:text>}</xsl:text>
754
</xsl:template>
755
756
<!-- strong -->
757
<xsl:template match="html:strong">
758
<xsl:text>\textbf{</xsl:text>
759
<xsl:apply-templates select="node()"/>
760
<xsl:text>}</xsl:text>
761
</xsl:template>
762
763
<!-- horizontal rule -->
764
<xsl:template match="html:hr">
765
<xsl:text>\vskip 2em
766
\hrule height 0.4pt
767
\vskip 2em
768
769
</xsl:text>
770
</xsl:template>
771
772
<!-- images -->
773
<xsl:template match="html:img">
774
<xsl:text>\begin{figure}
775
</xsl:text>
776
<xsl:text>\begin{center}
777
</xsl:text>
778
<xsl:if test="@width|@height">
779
<!-- there are dimensions, so use them -->
780
<!-- Basically, we allow any units covered by LaTeX, even
781
if they are not allowed in XHTML. px is converted to pt.
782
If no units, then assume pt.
783
-->
784
<xsl:text>\resizebox{</xsl:text>
785
<xsl:choose>
786
<xsl:when test="@width">
787
<xsl:call-template name="replace-substring">
788
<xsl:with-param name="original">
789
<xsl:value-of select="@width"/>
790
</xsl:with-param>
791
<xsl:with-param name="substring">
792
<xsl:text>px</xsl:text>
793
</xsl:with-param>
794
<xsl:with-param name="replacement">
795
<xsl:text>pt</xsl:text>
796
</xsl:with-param>
797
</xsl:call-template>
798
<xsl:if test="translate(@width,
799
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.'
800
,'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') = '' ">
801
<!-- no units specified -->
802
<xsl:text>pt</xsl:text>
803
</xsl:if>
804
</xsl:when>
805
<xsl:otherwise>
806
<xsl:text>!</xsl:text>
807
</xsl:otherwise>
808
</xsl:choose>
809
<xsl:text>}{</xsl:text>
810
<xsl:choose>
811
<xsl:when test="@height">
812
<xsl:call-template name="replace-substring">
813
<xsl:with-param name="original">
814
<xsl:value-of select="@height"/>
815
</xsl:with-param>
816
<xsl:with-param name="substring">
817
<xsl:text>px</xsl:text>
818
</xsl:with-param>
819
<xsl:with-param name="replacement">
820
<xsl:text>pt</xsl:text>
821
</xsl:with-param>
822
</xsl:call-template>
823
<xsl:if test="translate(@height,
824
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.'
825
,'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') = '' ">
826
<!-- no units specified -->
827
<xsl:text>pt</xsl:text>
828
</xsl:if>
829
</xsl:when>
830
<xsl:otherwise>
831
<xsl:text>!</xsl:text>
832
</xsl:otherwise>
833
</xsl:choose>
834
<xsl:text>}{</xsl:text>
835
</xsl:if>
836
<xsl:if test="not(@width|@height)">
837
<!-- if no dimensions, then ensure it fits on page
838
(of course, this also goes to "max zoom"...)
839
-->
840
<xsl:text>\resizebox{1\linewidth}{!}{</xsl:text>
841
</xsl:if>
842
<xsl:text>\includegraphics{</xsl:text>
843
<xsl:value-of select="@src"/>
844
<xsl:text>}}
845
\end{center}
846
</xsl:text>
847
<xsl:if test="@title">
848
<xsl:if test="not(@title = '')">
849
<xsl:text>\caption{</xsl:text>
850
<xsl:apply-templates select="@title"/>
851
<xsl:text>}
852
</xsl:text>
853
</xsl:if>
854
</xsl:if>
855
<xsl:if test="@id">
856
<xsl:text>\label{</xsl:text>
857
<xsl:value-of select="@id"/>
858
<xsl:text>}
859
</xsl:text>
860
</xsl:if>
861
<xsl:text>\end{figure}
862
</xsl:text>
863
</xsl:template>
864
865
<!-- footnotes -->
866
<xsl:template match="html:div">
867
<xsl:if test="not(@class = 'footnotes')">
868
<xsl:apply-templates select="node()"/>
869
</xsl:if>
870
</xsl:template>
871
872
<!-- pull-quotes (a table with no header, and a single column) -->
873
<!-- this is experimental, and I am open to suggestions -->
874
<xsl:template match="html:table[@class='pull-quote']">
875
<xsl:text>\begin{table}[htbp]
876
\begin{minipage}{\linewidth}
877
\centering
878
</xsl:text>
879
<xsl:apply-templates select="html:caption"/>
880
<xsl:text>\begin{tabular}{@{}p{0.5\linewidth}@{}} \\ \toprule </xsl:text>
881
<xsl:apply-templates select="html:thead"/>
882
<xsl:apply-templates select="html:tbody"/>
883
<xsl:apply-templates select="html:tr"/>
884
<xsl:text>\end{tabular}
885
\end{minipage}
886
\end{table}
887
888
</xsl:text>
889
</xsl:template>
890
891
<!-- tables -->
892
<xsl:template match="html:table">
893
<xsl:text>\begin{table}[htbp]
894
<!-- ===== vismor ===== -->
895
</xsl:text>
896
<xsl:apply-templates select="html:caption"/>
897
<xsl:text>\begin{minipage}{\linewidth}
898
<!-- ================== -->
899
\centering
900
\small
901
</xsl:text>
902
<!-- ===== vismor ===== -->
903
<xsl:text>\begin{tabular}{@{}</xsl:text>
904
<!-- ================== -->
905
<xsl:apply-templates select="html:col"/>
906
<xsl:text>@{}} \\ \toprule </xsl:text>
907
<xsl:apply-templates select="html:thead"/>
908
<xsl:apply-templates select="html:tbody"/>
909
<xsl:apply-templates select="html:tr"/>
910
<!-- ===== vismor ===== -->
911
<xsl:text>\end{tabular}
912
\\\medskip\medskip
913
<!-- ================== -->
914
\end{minipage}
915
\end{table}
916
917
</xsl:text>
918
</xsl:template>
919
920
<xsl:template match="html:tbody">
921
<xsl:apply-templates select="html:tr"/>
922
\bottomrule
923
</xsl:template>
924
925
<xsl:template match="html:col">
926
<xsl:choose>
927
<xsl:when test="@align='center'">
928
<xsl:choose>
929
<xsl:when test="@class='extended'">
930
<xsl:text>C</xsl:text>
931
</xsl:when>
932
<xsl:otherwise>
933
<xsl:text>c</xsl:text>
934
</xsl:otherwise>
935
</xsl:choose>
936
</xsl:when>
937
<xsl:when test="@align='right'">
938
<xsl:choose>
939
<xsl:when test="@class='extended'">
940
<xsl:text>R</xsl:text>
941
</xsl:when>
942
<xsl:otherwise>
943
<xsl:text>r</xsl:text>
944
</xsl:otherwise>
945
</xsl:choose>
946
</xsl:when>
947
<xsl:otherwise>
948
<xsl:choose>
949
<xsl:when test="@class='extended'">
950
<xsl:text>J</xsl:text>
951
</xsl:when>
952
<xsl:otherwise>
953
<xsl:text>l</xsl:text>
954
</xsl:otherwise>
955
</xsl:choose>
956
</xsl:otherwise>
957
</xsl:choose>
958
</xsl:template>
959
960
<xsl:template match="html:thead">
961
<xsl:apply-templates select="html:tr" mode="header"/>
962
<xsl:text>\midrule
963
</xsl:text>
964
</xsl:template>
965
966
<xsl:template match="html:caption">
967
<xsl:text>\caption{</xsl:text>
968
<xsl:apply-templates select="node()"/>
969
<xsl:text>}
970
</xsl:text>
971
<xsl:if test="@id">
972
<xsl:text>\label{</xsl:text>
973
<xsl:value-of select="@id"/>
974
<xsl:text>}
975
</xsl:text>
976
</xsl:if>
977
</xsl:template>
978
979
<xsl:template match="html:tr" mode="header">
980
<xsl:text>
981
</xsl:text>
982
<xsl:apply-templates select="html:td|html:th"/>
983
<xsl:text> \\ </xsl:text>
984
<!-- figure out a way to count columns for \cmidrule{x-y} -->
985
<xsl:apply-templates select="html:td[1]|html:th[1]" mode="cmidrule">
986
<xsl:with-param name="col" select="1"/>
987
</xsl:apply-templates>
988
</xsl:template>
989
990
<xsl:template match="html:td|html:th" mode="cmidrule">
991
<xsl:param name="col"/>
992
<xsl:param name="end" select="$col+format-number(@colspan,'#','string')-1"/>
993
<xsl:if test="not(. = '')">
994
<xsl:text> \cmidrule{</xsl:text>
995
<xsl:value-of select="$col"/>
996
<xsl:text>-</xsl:text>
997
<xsl:value-of select="$end"/>
998
<xsl:text>}</xsl:text>
999
</xsl:if>
1000
<xsl:apply-templates select="following-sibling::*[1]" mode="cmidrule">
1001
<xsl:with-param name="col" select="$end+1"/>
1002
</xsl:apply-templates>
1003
</xsl:template>
1004
1005
<xsl:template match="html:tr[last()]" mode="header">
1006
<xsl:text>
1007
</xsl:text>
1008
<xsl:apply-templates select="html:td|html:th"/>
1009
<xsl:text> \\</xsl:text>
1010
</xsl:template>
1011
1012
<xsl:template match="html:tr">
1013
<xsl:apply-templates select="html:td|html:th"/>
1014
<xsl:text> \\
1015
</xsl:text>
1016
</xsl:template>
1017
1018
<xsl:template match="html:th|html:td">
1019
<xsl:if test="@colspan">
1020
<xsl:text>\multicolumn{</xsl:text>
1021
<xsl:value-of select="@colspan"/>
1022
</xsl:if>
1023
<xsl:if test="@colspan">
1024
<xsl:text>}{c}{</xsl:text>
1025
</xsl:if>
1026
<xsl:apply-templates select="node()"/>
1027
<xsl:if test="@colspan">
1028
<xsl:text>}</xsl:text>
1029
</xsl:if>
1030
<xsl:if test="position()!=last()">
1031
<xsl:text>&amp;</xsl:text>
1032
</xsl:if>
1033
</xsl:template>
1034
1035
<!-- Support for Bibliography to BibTeX conversion -->
1036
1037
<xsl:template match="html:span[@class='externalcitation']">
1038
<xsl:text>\cite</xsl:text>
1039
<xsl:apply-templates select="html:span" mode="citation"/>
1040
<xsl:apply-templates select="html:a" mode="citation"/>
1041
<xsl:text>}</xsl:text>
1042
</xsl:template>
1043
1044
<xsl:template match="html:span[@class='markdowncitation']">
1045
<xsl:text>~\cite</xsl:text>
1046
<xsl:apply-templates select="html:span" mode="citation"/>
1047
<xsl:apply-templates select="html:a" mode="markdowncitation"/>
1048
<xsl:text>}</xsl:text>
1049
</xsl:template>
1050
1051
<xsl:template match="html:span[@class='notcited']">
1052
<xsl:text>~\nocite{</xsl:text>
1053
<xsl:value-of select="@id"/>
1054
<xsl:text>}</xsl:text>
1055
</xsl:template>
1056
1057
<xsl:template match="html:a[@id]" mode="citation">
1058
<xsl:text>{</xsl:text>
1059
<xsl:value-of select="@id"/>
1060
</xsl:template>
1061
1062
<xsl:template match="html:a[@href]" mode="markdowncitation">
1063
<xsl:text>{</xsl:text>
1064
<xsl:value-of select="substring-after(@href,'#')"/>
1065
</xsl:template>
1066
1067
<xsl:template match="html:span[@class='locator']" mode="citation">
1068
<xsl:text>[</xsl:text>
1069
<xsl:value-of select="."/>
1070
<xsl:text>]</xsl:text>
1071
</xsl:template>
1072
1073
<!-- Disabled unless natbib is implemented -->
1074
<xsl:template match="html:span[@class='textual citation']" mode="citation">
1075
<xsl:text></xsl:text>
1076
</xsl:template>
1077
1078
<xsl:template match="html:div[@class='bibliography']">
1079
<xsl:text>\begin{thebibliography}{</xsl:text>
1080
<xsl:value-of select="count(div[@id])"/>
1081
<xsl:text>}
1082
</xsl:text>
1083
<xsl:apply-templates select="html:div"/>
1084
<xsl:text>
1085
1086
\end{thebibliography}
1087
1088
</xsl:text>
1089
</xsl:template>
1090
1091
<xsl:template match="html:div[@class='bibliography']/html:div[@id]">
1092
<xsl:text>
1093
1094
\bibitem{</xsl:text>
1095
<xsl:value-of select="@id"/>
1096
<xsl:text>}
1097
</xsl:text>
1098
<xsl:apply-templates select="html:p/html:span[@class='item']" mode="citation"/>
1099
</xsl:template>
1100
1101
<xsl:template match="html:span[@class='item']" mode="citation">
1102
<xsl:apply-templates select="."/>
1103
</xsl:template>
1104
1105
1106
<!-- Default LaTeX code to add -->
1107
1108
<xsl:template name="latex-header">
1109
<xsl:text>
1110
<!-- ===== vismor ===== -->
1111
\usepackage{amsmath} % Enhanced equation typesetting
1112
1113
\usepackage{unicode-math} % XeLaTeX font configuration
1114
\setmathfont{XITS Math}
1115
\defaultfontfeatures{Scale=MatchLowercase,Mapping=tex-text}
1116
\setmainfont{Adobe Garamond Pro}
1117
\setsansfont{Myriad Pro}
1118
\setmonofont{Menlo}
1119
1120
\usepackage{xunicode} % Xelatex support
1121
1122
\usepackage{fancyvrb,relsize} % Allow \verbatim et al. in footnotes
1123
\usepackage{graphicx} % To include graphics in pdf's (jpg, gif, png, etc)
1124
\usepackage{booktabs} % Better tables
1125
\usepackage{tabularx}
1126
\usepackage{threeparttable} % Support for table footnotes
1127
\usepackage[svgnames]{xcolor} % Allow for color (annotations)
1128
\usepackage{fancyhdr}
1129
1130
\usepackage{listings} % Used to display algorithms
1131
\usepackage{alltt} % Added flexibility over vanilla verbatim
1132
1133
\pagestyle{fancy}
1134
\headheight=14pt
1135
<!-- ================== -->
1136
1137
\def\myauthor{Author} % In case these were not included in metadata
1138
\def\mytitle{Title}
1139
\def\mykeywords{}
1140
\def\mybibliostyle{plain}
1141
\def\bibliocommand{}
1142
1143
<!-- ===== vismor ===== -->
1144
\ifx \VerbatimFootnotes \undefined
1145
\else
1146
\VerbatimFootnotes
1147
\fi
1148
\ifx \DefineVerbatimEnvironment \undefined
1149
\else
1150
\DefineVerbatimEnvironment%
1151
{verbatim}{Verbatim}
1152
{numbers=none, fontsize=\relsize{-1},frame=none}
1153
\fi
1154
<!-- ================== -->
1155
</xsl:text>
1156
</xsl:template>
1157
1158
<xsl:template name="latex-intro">
1159
<xsl:text>
1160
1161
%
1162
% PDF Stuff
1163
%
1164
<!-- ===== vismor ===== -->
1165
\usepackage[
1166
plainpages=false,
1167
pdfpagelabels,
1168
pdftitle={\mytitle},
1169
pagebackref,
1170
pdfauthor={\myauthor},
1171
pdfkeywords={\mykeywords},
1172
colorlinks=true,
1173
citecolor=MidnightBlue,
1174
linkcolor=MidnightBlue,
1175
urlcolor=MidnightBlue
1176
]{hyperref}
1177
<!-- ================== -->
1178
1179
1180
%
1181
% Title Information
1182
%
1183
1184
1185
\ifx\latexauthor\undefined
1186
\else
1187
\def\myauthor{\latexauthor}
1188
\fi
1189
1190
\ifx\subtitle\undefined
1191
\else
1192
\addtodef{\mytitle}{}{ \\ \subtitle}
1193
\fi
1194
1195
\ifx\affiliation\undefined
1196
\else
1197
\addtodef{\myauthor}{}{ \\ \affiliation}
1198
\fi
1199
1200
\ifx\address\undefined
1201
\else
1202
\addtodef{\myauthor}{}{ \\ \address}
1203
\fi
1204
1205
\ifx\phone\undefined
1206
\else
1207
\addtodef{\myauthor}{}{ \\ \phone}
1208
\fi
1209
1210
\ifx\email\undefined
1211
\else
1212
\addtodef{\myauthor}{}{ \\ \email}
1213
\fi
1214
1215
\ifx\web\undefined
1216
\else
1217
\addtodef{\myauthor}{}{ \\ \web}
1218
\fi
1219
1220
\title{\mytitle}
1221
\author{\myauthor}
1222
1223
<!-- ===== vismor ===== -->
1224
\renewcommand{\lstlistlistingname}{List of Algorithms}
1225
\renewcommand{\lstlistingname}{Algorithm}
1226
\lstset{
1227
language=C,
1228
mathescape=true
1229
}
1230
<!-- ================== -->
1231
1232
\begin{document}
1233
</xsl:text>
1234
</xsl:template>
1235
1236
<xsl:template name="latex-paper-size">
1237
</xsl:template>
1238
1239
<xsl:template name="latex-footer">
1240
<xsl:text>% Bibliography
1241
\bibliographystyle{\mybibliostyle}
1242
\bibliocommand
1243
1244
\end{document}
1245
</xsl:text>
1246
</xsl:template>
1247
1248
1249
<!-- Allow for spans to set a color
1250
Specifically, this is useful with Scrivener -->
1251
<xsl:template match="html:span[starts-with(@style,'color:')]">
1252
<xsl:text>{\color[HTML]{</xsl:text>
1253
<xsl:call-template name="replace-substring">
1254
<xsl:with-param name="original">
1255
<xsl:value-of select="@style"/>
1256
</xsl:with-param>
1257
<xsl:with-param name="substring">
1258
<xsl:text>color:#</xsl:text>
1259
</xsl:with-param>
1260
<xsl:with-param name="replacement">
1261
<xsl:text></xsl:text>
1262
</xsl:with-param>
1263
</xsl:call-template>
1264
<xsl:text>} </xsl:text>
1265
<xsl:apply-templates select="node()"/>
1266
<xsl:text>}</xsl:text>
1267
</xsl:template>
1268
1269
<!-- replace-substring routine by Doug Tidwell - XSLT, O'Reilly Media -->
1270
<xsl:template name="replace-substring">
1271
<xsl:param name="original" />
1272
<xsl:param name="substring" />
1273
<xsl:param name="replacement" select="''"/>
1274
<xsl:variable name="first">
1275
<xsl:choose>
1276
<xsl:when test="contains($original, $substring)" >
1277
<xsl:value-of select="substring-before($original, $substring)"/>
1278
</xsl:when>
1279
<xsl:otherwise>
1280
<xsl:value-of select="$original"/>
1281
</xsl:otherwise>
1282
</xsl:choose>
1283
</xsl:variable>
1284
<xsl:variable name="middle">
1285
<xsl:choose>
1286
<xsl:when test="contains($original, $substring)" >
1287
<xsl:value-of select="$replacement"/>
1288
</xsl:when>
1289
<xsl:otherwise>
1290
<xsl:text></xsl:text>
1291
</xsl:otherwise>
1292
</xsl:choose>
1293
</xsl:variable>
1294
<xsl:variable name="last">
1295
<xsl:choose>
1296
<xsl:when test="contains($original, $substring)">
1297
<xsl:choose>
1298
<xsl:when test="contains(substring-after($original, $substring), $substring)">
1299
<xsl:call-template name="replace-substring">
1300
<xsl:with-param name="original">
1301
<xsl:value-of select="substring-after($original, $substring)" />
1302
</xsl:with-param>
1303
<xsl:with-param name="substring">
1304
<xsl:value-of select="$substring" />
1305
</xsl:with-param>
1306
<xsl:with-param name="replacement">
1307
<xsl:value-of select="$replacement" />
1308
</xsl:with-param>
1309
</xsl:call-template>
1310
</xsl:when>
1311
<xsl:otherwise>
1312
<xsl:value-of select="substring-after($original, $substring)"/>
1313
</xsl:otherwise>
1314
</xsl:choose>
1315
</xsl:when>
1316
<xsl:otherwise>
1317
<xsl:text></xsl:text>
1318
</xsl:otherwise>
1319
</xsl:choose>
1320
</xsl:variable>
1321
<xsl:value-of select="concat($first, $middle, $last)"/>
1322
</xsl:template>
1323
</xsl:stylesheet>
1324