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