book2html generates full page
[librarian.git] / librarian / xslt / book2html.xslt
1 <?xml version="1.0" encoding="utf-8"?>
2 <!--
3
4    This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
5    Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
6
7 -->
8 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
9     xmlns:wl="http://wolnelektury.pl/functions" >
10
11 <xsl:output encoding="utf-8" indent="yes" omit-xml-declaration = "yes" version="2.0" />
12 <xsl:template match="utwor">
13     <xsl:choose>
14         <xsl:when test="@full-page">
15             <html>
16             <head>
17                 <title>Książka z serwisu WolneLektury.pl</title>
18                 <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
19             </head>
20             <style>
21                 body {
22                     font-size: 16px;
23                     font: Georgia, "Times New Roman", serif;
24                     line-height: 1.5em;
25                     margin: 0;
26                 }
27
28                 a {
29                     color: blue;
30                     text-decoration: none;
31                 }
32
33                 #book-text {
34                     margin: 3em;
35                     max-width: 36em;
36                 }
37
38                 /* ================================== */
39                 /* = Header with logo and menu      = */
40                 /* ================================== */
41                 #header {
42                     margin: 3.4em 0 0 1.4em;
43                 }
44
45                 img {
46                     border: none;
47                 }
48
49
50                 #menu {
51                     position: fixed;
52                     left: 0em;
53                     top: 0em;
54                     width: 100%;
55                     height: 1.5em;
56                     background: #333;
57                     color: #FFF;
58                     opacity: 0.9;
59                     z-index: 99;
60                 }
61
62                 #menu ul {
63                     list-style: none;
64                     padding: 0;
65                     margin: 0;
66                 }
67
68                 #menu li a {
69                     display: block;
70                     float: left;
71                     width: 7.5em;
72                     height: 1.5em;
73                     margin-left: 0.5em;
74                     text-align: center;
75                     color: #FFF;
76                 }
77
78                 #menu li a:hover, #menu li a:active {
79                     color: #000;
80                     background: #FFF url(/static/img/arrow-down.png) no-repeat center right;
81                 }
82
83                 #menu li a.selected {
84                     color: #000;
85                     background: #FFF url(/static/img/arrow-up.png) no-repeat center right;
86                 }
87                 #menu a.menu-link {
88                     display: block;
89                     float: left;
90                     height: 1.5em;
91                     margin-left: 0.5em;
92                     text-align: center;
93                     color: #FFF;
94                 }
95                 #menu span {
96                     color: #888;
97                     font-style: italic;
98                     font-size: .75em;
99                     margin-right: 0.5em;
100                 }
101
102
103                 #toc, #themes, #nota_red {
104                     position: fixed;
105                     left: 0em;
106                     top: 1.5em;
107                     width: 37em;
108                     padding: 1.5em;
109                     background: #FFF;
110                     border-bottom: 0.25em solid #DDD;
111                     border-right: 0.25em solid #DDD;
112                     display: none;
113                     height: 16em;
114                     overflow-x: hidden;
115                     overflow-y: auto;
116                     opacity: 0.9;
117                     z-index: 99;
118                 }
119
120                 #toc ol, #themes ol {
121                     list-style: none;
122                     padding: 0;
123                     margin: 0;
124                 }
125
126                 #toc ol li {
127                     font-weight: bold;
128                 }
129
130                 #toc ol ol {
131                     padding: 0 0 1.5em 1.5em;
132                     margin: 0;
133                 }
134
135                 #toc ol ol li {
136                     font-weight: normal;
137                 }
138
139                 #toc h2 {
140                     display: none;
141                 }
142
143                 #toc .anchor {
144                     float: none;
145                     margin: 0;
146                     color: blue;
147                     font-size: 16px;
148                     position: inherit;
149                 }
150
151                 /* =================================================== */
152                 /* = Common elements: headings, paragraphs and lines = */
153                 /* =================================================== */
154                 h1 {
155                     font-size: 3em;
156                     margin: 1.5em 0;
157                     text-align: center;
158                     line-height: 1.5em;
159                     font-weight: bold;
160                 }
161
162                 h2 {
163                     font-size: 2em;
164                     margin: 1.5em 0 0;
165                     font-weight: bold;
166                     line-height: 1.5em;
167                 }
168
169                 h3 {
170                     font-size: 1.5em;
171                     margin: 1.5em 0 0;
172                     font-weight: normal;
173                     line-height: 1.5em;
174                 }
175
176                 h4 {
177                     font-size: 1em;
178                     margin: 1.5em 0 0;
179                     line-height: 1.5em;
180                 }
181
182                 p {
183                     margin: 0;
184                 }
185
186                 /* ======================== */
187                 /* = Footnotes and themes = */
188                 /* ======================== */
189                 .theme-begin {
190                     border-left: 0.1em solid #DDDDDD;
191                     color: #777;
192                     padding: 0 0.5em;
193                     width: 7.5em;
194
195                     font-style: normal;
196                     font-weight: normal;
197                     font-variant: normal;
198                     letter-spacing: 0;
199                     text-transform: none;
200                     text-decoration: none;
201
202                     font-size: 16px;
203                     float: right;
204                     margin-right: -9.5em;
205                     margin-bottom: 0.5em;
206                     clear: both;
207                     left: 40em;
208                     line-height: 1.5em;
209                     text-align: left;
210                 }
211
212                 .annotation {
213                     font-style: normal;
214                     font-weight: normal;
215                     font-size: 12px;
216                     padding-left: 2px;
217                     position: relative;
218                     top: -4px;
219                 }
220
221                 #footnotes .annotation {
222                     display: block;
223                     float: left;
224                     width: 2.5em;
225                     clear: both;
226                 }
227
228                 #footnotes div {
229                     margin: 1.5em 0 0 0;
230                 }
231
232                 #footnotes p {
233                     margin-left: 2.5em;
234                     font-size: 0.875em;
235                 }
236
237                 blockquote {
238                     font-size: 0.875em;
239                 }
240
241                 /* ============= */
242                 /* = Numbering = */
243                 /* ============= */
244                 .verse, .paragraph {
245                     position:relative;
246                 }
247                 .anchor {
248                     position: absolute;
249                     margin: -0.25em -0.5em;
250                     left: -3em;
251                     color: #777;
252                     font-size: 12px;
253                     width: 2em;
254                     text-align: center;
255                     padding: 0.25em 0.5em;
256                     line-height: 1.5em;
257                 }
258
259                 .anchor:hover, #book-text .anchor:active {
260                     color: #FFF;
261                     background-color: #CCC;
262                 }
263
264                 /* =================== */
265                 /* = Custom elements = */
266                 /* =================== */
267                 span.author {
268                     font-size: 0.5em;
269                     display: block;
270                     line-height: 1.5em;
271                     margin-bottom: 0.25em;
272                 }
273
274                 span.collection {
275                     font-size: 0.375em;
276                     display: block;
277                     line-height: 1.5em;
278                     margin-bottom: -0.25em;
279                 }
280
281                 span.subtitle {
282                     font-size: 0.5em;
283                     display: block;
284                     line-height: 1.5em;
285                     margin-top: -0.25em;
286                 }
287
288                 div.didaskalia {
289                     font-style: italic;
290                     margin: 0.5em 0 0 1.5em;
291                 }
292
293                 div.kwestia {
294                     margin: 0.5em 0 0;
295                 }
296
297                 div.stanza {
298                     margin: 1.5em 0 0;
299                 }
300
301                 div.kwestia div.stanza {
302                     margin: 0;
303                 }
304
305                 p.paragraph {
306                     text-align: justify;
307                     margin: 1.5em 0 0;
308                 }
309
310                 p.motto {
311                     text-align: justify;
312                     font-style: italic;
313                     margin: 1.5em 0 0;
314                 }
315
316                 p.motto_podpis {
317                     font-size: 0.875em;
318                     text-align: right;
319                 }
320
321                 div.fragment {
322                     border-bottom: 0.1em solid #999;
323                     padding-bottom: 1.5em;
324                 }
325
326                 div.note p, div.dedication p, div.note p.paragraph, div.dedication p.paragraph {
327                     text-align: right;
328                     font-style: italic;
329                 }
330
331                 hr.spacer {
332                     height: 3em;
333                     visibility: hidden;
334                 }
335
336                 hr.spacer-line {
337                     margin: 1.5em 0;
338                     border: none;
339                     border-bottom: 0.1em solid #000;
340                 }
341
342                 p.spacer-asterisk {
343                     padding: 0;
344                     margin: 1.5em 0;
345                     text-align: center;
346                 }
347
348                 div.person-list ol {
349                     list-style: none;
350                     padding: 0 0 0 1.5em;
351                 }
352
353                 p.place-and-time {
354                     font-style: italic;
355                 }
356
357                 em.math, em.foreign-word, em.book-title, em.didaskalia {
358                     font-style: italic;
359                 }
360
361                 em.author-emphasis {
362                     letter-spacing: 0.1em;
363                 }
364
365                 em.person {
366                     font-style: normal;
367                     font-variant: small-caps;
368                 }
369
370                 .verse:after {
371                     content: "\feff";
372                 }
373
374
375                 /* =================================== */
376                 /* = Hide some elements for printing = */
377                 /* =================================== */
378
379                 @media print {
380                     #menu {display: none;}
381                 }
382             </style>
383             <body>
384                 <xsl:call-template name="book-text" />
385             </body>
386             </html>
387         </xsl:when>
388         <xsl:otherwise>
389             <xsl:call-template name="book-text" />
390         </xsl:otherwise>
391     </xsl:choose>
392 </xsl:template>
393
394 <xsl:template name="book-text">
395     <div id="book-text">
396         <xsl:apply-templates select="powiesc|opowiadanie|liryka_l|liryka_lp|dramat_wierszowany_l|dramat_wierszowany_lp|dramat_wspolczesny" />
397         <xsl:if test="count(descendant::*[self::pe or self::pa or self::pr or self::pt][not(parent::extra)])">
398             <div id="footnotes">
399                 <h3>Przypisy</h3>
400                 <xsl:for-each select="descendant::*[self::pe or self::pa or self::pr or self::pt][not(parent::extra)]">
401                     <div>
402                         <a name="{concat('footnote-', generate-id(.))}" />
403                         <a href="{concat('#anchor-', generate-id(.))}" class="annotation">[<xsl:number value="count(preceding::*[self::pa or self::pe or self::pr or self::pt]) + 1" />]</a>
404                         <xsl:choose>
405                             <xsl:when test="count(akap|akap_cd|strofa) = 0">
406                                 <p><xsl:apply-templates select="text()|*" mode="inline" /></p>
407                             </xsl:when>
408                             <xsl:otherwise>
409                                 <xsl:apply-templates select="text()|*" mode="inline" />
410                             </xsl:otherwise>
411                         </xsl:choose>
412                     </div>
413                 </xsl:for-each>
414             </div>
415         </xsl:if>
416     </div>
417 </xsl:template>
418
419
420 <!-- ============================================================================== -->
421 <!-- = MASTER TAG                                                                 = -->
422 <!-- = (can contain block tags, paragraph tags, standalone tags and special tags) = -->
423 <!-- ============================================================================== -->
424 <xsl:template match="powiesc|opowiadanie|liryka_l|liryka_lp|dramat_wierszowany_l|dramat_wierszowany_lp|dramat_wspolczesny">
425     <xsl:apply-templates select="nota_red" mode="special" />
426     <xsl:if test="nazwa_utworu">
427         <h1>
428             <xsl:apply-templates select="autor_utworu|dzielo_nadrzedne|nazwa_utworu|podtytul" mode="header" />
429         </h1>
430     </xsl:if>
431     <xsl:apply-templates />
432 </xsl:template>
433
434
435 <!-- ==================================================================================== -->
436 <!-- = BLOCK TAGS                                                                       = -->
437 <!-- = (can contain other block tags, paragraph tags, standalone tags and special tags) = -->
438 <!-- ==================================================================================== -->
439 <xsl:template match="nota">
440     <div class="note"><xsl:apply-templates /></div>
441 </xsl:template>
442
443 <xsl:template match="lista_osob">
444     <div class="person-list">
445         <h3><xsl:value-of select="naglowek_listy" /></h3>
446         <ol>
447             <xsl:apply-templates select="lista_osoba" />
448         </ol>
449     </div>
450 </xsl:template>
451
452 <xsl:template match="dedykacja">
453     <div class="dedication"><xsl:apply-templates /></div>
454 </xsl:template>
455
456 <xsl:template match="kwestia">
457     <div class="kwestia">
458         <xsl:apply-templates select="strofa|akap|didaskalia" />
459     </div>
460 </xsl:template>
461
462 <xsl:template match="dlugi_cytat|poezja_cyt">
463     <blockquote><xsl:apply-templates /></blockquote>
464 </xsl:template>
465
466 <xsl:template match="motto">
467     <div class="motto"><xsl:apply-templates mode="inline" /></div>
468 </xsl:template>
469
470
471 <!-- ========================================== -->
472 <!-- = PARAGRAPH TAGS                         = -->
473 <!-- = (can contain inline and special tags)  = -->
474 <!-- ========================================== -->
475 <!-- Title page -->
476 <xsl:template match="autor_utworu" mode="header">
477     <span class="author"><xsl:apply-templates mode="inline" /></span>
478 </xsl:template>
479
480 <xsl:template match="nazwa_utworu" mode="header">
481     <span class="title"><xsl:apply-templates mode="inline" /></span>
482 </xsl:template>
483
484 <xsl:template match="dzielo_nadrzedne" mode="header">
485     <span class="collection"><xsl:apply-templates mode="inline" /></span>
486 </xsl:template>
487
488 <xsl:template match="podtytul" mode="header">
489     <span class="subtitle"><xsl:apply-templates mode="inline" /></span>
490 </xsl:template>
491
492 <!-- Section headers (included in index)-->
493 <xsl:template match="naglowek_akt|naglowek_czesc|srodtytul">
494     <h2><xsl:apply-templates mode="inline" /></h2>
495 </xsl:template>
496
497 <xsl:template match="naglowek_scena|naglowek_rozdzial">
498     <h3><xsl:apply-templates mode="inline" /></h3>
499 </xsl:template>
500
501 <xsl:template match="naglowek_osoba|naglowek_podrozdzial">
502     <h4><xsl:apply-templates mode="inline" /></h4>
503 </xsl:template>
504
505 <!-- Other paragraph tags -->
506 <xsl:template match="miejsce_czas">
507     <p class="place-and-time"><xsl:apply-templates mode="inline" /></p>
508 </xsl:template>
509
510 <xsl:template match="didaskalia">
511     <div class="didaskalia"><xsl:apply-templates mode="inline" /></div>
512 </xsl:template>
513
514 <xsl:template match="lista_osoba">
515     <li><xsl:apply-templates mode="inline" /></li>
516 </xsl:template>
517
518 <xsl:template match="akap|akap_dialog|akap_cd">
519     <p class="paragraph"><xsl:apply-templates mode="inline" /></p>
520 </xsl:template>
521
522 <xsl:template match="strofa">
523     <div class="stanza">
524         <xsl:choose>
525             <xsl:when test="count(br) > 0">
526                 <xsl:call-template name="verse">
527                     <xsl:with-param name="verse-content" select="br[1]/preceding-sibling::text() | br[1]/preceding-sibling::node()" />
528                     <xsl:with-param name="verse-type" select="br[1]/preceding-sibling::*[name() = 'wers_wciety' or name() = 'wers_akap' or name() = 'wers_cd'][1]" />
529                 </xsl:call-template>
530                 <xsl:for-each select="br">              
531                                 <!-- Each BR tag "consumes" text after it -->
532                     <xsl:variable name="lnum" select="count(preceding-sibling::br)" />
533                     <xsl:call-template name="verse">
534                         <xsl:with-param name="verse-content"
535                             select="following-sibling::text()[count(preceding-sibling::br) = $lnum+1] | following-sibling::node()[count(preceding-sibling::br) = $lnum+1]" />
536                         <xsl:with-param name="verse-type" select="following-sibling::*[count(preceding-sibling::br) = $lnum+1 and (name() = 'wers_wciety' or name() = 'wers_akap' or name() = 'wers_cd')][1]" />
537                     </xsl:call-template>
538                 </xsl:for-each>
539             </xsl:when>
540             <xsl:otherwise>
541                 <xsl:call-template name="verse">
542                     <xsl:with-param name="verse-content" select="text() | node()" />
543                     <xsl:with-param name="verse-type" select="wers_wciety|wers_akap|wers_cd[1]" />
544                  </xsl:call-template>
545             </xsl:otherwise>
546         </xsl:choose>
547     </div>
548 </xsl:template>
549
550 <xsl:template name="verse">
551     <xsl:param name="verse-content" />
552     <xsl:param name="verse-type" />
553     <p class="verse">
554         <xsl:choose>
555             <xsl:when test="name($verse-type) = 'wers_akap'">
556                 <xsl:attribute name="style">padding-left: 1em</xsl:attribute>
557             </xsl:when>
558             <xsl:when test="name($verse-type) = 'wers_wciety'">
559                 <xsl:choose>
560                     <xsl:when test="$verse-content/@typ">
561                         <xsl:attribute name="style">padding-left: <xsl:value-of select="$verse-content/@typ" />em</xsl:attribute>
562                     </xsl:when>
563                     <xsl:otherwise>
564                         <xsl:attribute name="style">padding-left: 1em</xsl:attribute>
565                     </xsl:otherwise>
566                 </xsl:choose>
567             </xsl:when>
568             <xsl:when test="name($verse-type) = 'wers_cd'">
569                 <xsl:attribute name="style">padding-left: 12em</xsl:attribute>
570             </xsl:when>
571         </xsl:choose>
572         <xsl:apply-templates select="$verse-content" mode="inline" />
573     </p>
574 </xsl:template>
575
576 <xsl:template match="motto_podpis">
577     <p class="motto_podpis"><xsl:apply-templates mode="inline" /></p>
578 </xsl:template>
579
580
581 <!-- ================================================ -->
582 <!-- = INLINE TAGS                                  = -->
583 <!-- = (contain other inline tags and special tags) = -->
584 <!-- ================================================ -->
585 <!-- Annotations -->
586 <xsl:template match="pa|pe|pr|pt" mode="inline">
587     <a name="{concat('anchor-', generate-id(.))}" />
588     <a href="{concat('#footnote-', generate-id(.))}" class="annotation">[<xsl:number value="count(preceding::*[self::pa or self::pe or self::pr or self::pt]) + 1" />]</a>
589 </xsl:template>
590
591 <!-- Other inline tags -->
592 <xsl:template match="mat" mode="inline">
593     <em class="math"><xsl:apply-templates mode="inline" /></em>
594 </xsl:template>
595
596 <xsl:template match="didask_tekst" mode="inline">
597     <em class="didaskalia"><xsl:apply-templates mode="inline" /></em>
598 </xsl:template>
599
600 <xsl:template match="slowo_obce" mode="inline">
601     <em class="foreign-word"><xsl:apply-templates mode="inline" /></em>
602 </xsl:template>
603
604 <xsl:template match="tytul_dziela" mode="inline">
605     <em class="book-title">
606         <xsl:if test="@typ = '1'">„</xsl:if><xsl:apply-templates mode="inline" /><xsl:if test="@typ = '1'">”</xsl:if>
607     </em>
608 </xsl:template>
609
610 <xsl:template match="wyroznienie" mode="inline">
611     <em class="author-emphasis"><xsl:apply-templates mode="inline" /></em>
612 </xsl:template>
613
614 <xsl:template match="osoba" mode="inline">
615     <em class="person"><xsl:apply-templates mode="inline" /></em>
616 </xsl:template>
617
618
619 <!-- ============================================== -->
620 <!-- = STANDALONE TAGS                            = -->
621 <!-- = (cannot contain any other tags)            = -->
622 <!-- ============================================== -->
623 <xsl:template match="sekcja_swiatlo">
624     <hr class="spacer" />
625 </xsl:template>
626
627 <xsl:template match="sekcja_asterysk">
628     <p class="spacer-asterisk">*</p>
629 </xsl:template>
630
631 <xsl:template match="separator_linia">
632     <hr class="spacer-line" />
633 </xsl:template>
634
635
636 <!-- ================ -->
637 <!-- = SPECIAL TAGS = -->
638 <!-- ================ -->
639 <!-- Themes -->
640 <xsl:template match="begin" mode="inline">
641     <xsl:variable name="mnum" select="concat('m', substring(@id, 2))" />
642     <a name="m{substring(@id, 2)}" class="theme-begin" fid="{substring(@id, 2)}">
643         <xsl:value-of select="string(following::motyw[@id=$mnum]/text())" />
644     </a>
645 </xsl:template>
646
647 <xsl:template match="end" mode="inline">
648     <span class="theme-end" fid="{substring(@id, 2)}"> </span>
649 </xsl:template>
650
651 <xsl:template match="begin|end">
652     <xsl:apply-templates select='.' mode="inline" />
653 </xsl:template>
654
655 <xsl:template match="motyw" mode="inline" />
656
657
658 <xsl:template match="nota_red" mode="special">
659     <div id="nota_red">
660         <xsl:apply-templates />
661     </div>
662 </xsl:template>
663
664
665 <!-- ================ -->
666 <!-- = IGNORED TAGS = -->
667 <!-- ================ -->
668 <xsl:template match="extra|uwaga" />
669 <xsl:template match="extra|uwaga" mode="inline" />
670
671 <xsl:template match="nota_red" />
672
673 <!-- ======== -->
674 <!-- = TEXT = -->
675 <!-- ======== -->
676 <xsl:template match="text()" />
677 <xsl:template match="text()" mode="inline">
678     <xsl:value-of select="wl:substitute_entities(.)" />
679 </xsl:template>
680
681
682 </xsl:stylesheet>