Initial commit.
[wl2pdf.git] / xslt / wl2fo.xslt
1 <?xml version="1.0" encoding="utf-8"?>
2 <!-- 
3     Copyright © 2009,2010 Łukasz Rekucki
4
5     This file is part of WL2PDF
6
7     WL2PDF is free software: you can redistribute it and/or modify
8     it under the terms of the GNU Affero General Public License as published by
9     the Free Software Foundation, either version 3 of the License, or
10     (at your option) any later version.
11
12     WL2PDF is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU Affero General Public License for more details.
16
17     You should have received a copy of the GNU Affero General Public License
18     along with WL2PDF.  If not, see <http://www.gnu.org/licenses/>.
19  -->
20 <xsl:stylesheet version="2.0"
21
22     xmlns:wlml="http://nowoczesnapolska.org.pl/ML/Lektury/1.1"
23         
24         xmlns:xs="http://www.w3.org/2001/XMLSchema"
25     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
26        
27     xmlns:fo="http://www.w3.org/1999/XSL/Format"
28     xmlns:wlf="http://wolnelektury.pl/functions" >
29
30
31     <!-- generic template parameters -->
32     <xsl:param name="base-font-size" select="xs:integer(12)" />
33     <xsl:param name="base-font" select="'DejaVu Serif'" />        
34     
35     <xsl:variable name="footnote-font-size" select="$base-font-size - 2" />
36     <xsl:variable name="header-font-size" select="$base-font-size" />                                   
37           
38     <xsl:include href="wl2fo_pagemaster.xsl" />    
39     
40     <xsl:output method="xml"
41         encoding="utf-8"
42         indent="yes"
43         omit-xml-declaration = "yes" />
44
45
46     <!-- main templates -->
47     <xsl:template match="/">
48         <fo:root >
49             <xsl:call-template name="layout-masters" />
50
51             <fo:page-sequence master-reference="book-titles">
52                 <xsl:call-template name="title-page" />
53             </fo:page-sequence>
54
55             <fo:page-sequence
56                 language="pl"
57                 master-reference="main"
58                 initial-page-number="1"
59                 force-page-count="even">
60
61
62                  <!-- RUNNING HEADERS -->
63
64                 <fo:static-content
65                     flow-name="xsl-footnote-separator">
66                     <fo:block text-align-last="justify"><fo:leader leader-pattern="rule"/></fo:block>
67                 </fo:static-content>
68
69                 <fo:static-content
70                     flow-name="odd-after" font-family="{$base-font}" text-align="center">
71                     <fo:block>
72                         <fo:page-number />
73                     </fo:block>
74                 </fo:static-content>
75
76                 <fo:static-content
77                     flow-name="even-after" font-family="{$base-font}" text-align="center">
78                     <fo:block>
79                         <fo:page-number />
80                     </fo:block>
81                 </fo:static-content>
82
83
84                 <fo:static-content
85                     flow-name="even-before"
86                     font-family="DejaVu Serif"
87                     text-align="right">
88
89                     <fo:block border-bottom-width="0.2mm"
90                         border-bottom-style="solid"
91                         border-bottom-color="black">
92                            <fo:retrieve-marker retrieve-class-name="odd-header" />
93                     </fo:block>
94                 </fo:static-content>
95
96                 <fo:static-content
97                     flow-name="odd-before"
98                     font-family="DejaVu Serif"
99                     text-align="left">
100                         
101                     <fo:block border-after-width="0.2mm"
102                         border-after-style="solid"
103                         border-after-color="black">
104                         <fo:retrieve-marker retrieve-class-name="even-header" />
105                     </fo:block>
106                 </fo:static-content>
107
108                 <fo:flow 
109                         flow-name="xsl-region-body" 
110                         font-family="{$base-font}"
111                         font-size="{concat($base-font-size, 'pt')}"
112                     line-height-shift-adjustment="disregard-shifts" >
113                     
114                     <fo:marker marker-class-name="even-header">
115                         <xsl:value-of select="//wlml:author" />
116                     </fo:marker>
117                     <fo:marker marker-class-name="odd-header">
118                         <xsl:value-of select="//wlml:title" />
119                     </fo:marker>
120
121                     <xsl:apply-templates select="//wlml:main-text" />
122                 </fo:flow>
123             </fo:page-sequence>
124         </fo:root>
125     </xsl:template>
126
127     <xsl:template match="wlml:main-text">        
128         <xsl:apply-templates select="child::*" />
129     </xsl:template>
130
131 <!-- 
132     PROZA: elementy proste 
133 -->
134
135     <xsl:template match="wlml:chapter">
136         <fo:block text-align="left" font-size="300%"
137             font-weight="bold" 
138             page-break-before="right">
139             
140             <fo:marker marker-class-name="even-header">
141                 <xsl:apply-templates select="node()" />
142             </fo:marker>
143             <xsl:apply-templates select="node()" />            
144         </fo:block>
145     </xsl:template>
146
147     <xsl:template match="wlml:p">
148         <fo:block               
149             text-align="justify"
150             hyphenate="true" line-height="1.5"
151             space-before="1em"
152             space-after="1em"
153             text-indent="1.5em">
154             <xsl:apply-templates select="child::node()" />
155         </fo:block>
156     </xsl:template>
157
158     <xsl:template match="wlml:pd">
159         <fo:block text-align="justify" hyphenate="true" line-height="1.5"
160         space-before="1em" 
161         space-after="1em" 
162         text-indent="1.5em"
163     >&#x2014;<fo:character character="&#x2060;" /><fo:character character="&#x2002;" /><xsl:apply-templates select="child::node()" />
164         </fo:block>
165     </xsl:template>
166
167 <!-- 
168     POEZJA
169 -->
170     <xsl:template match="wlml:stanza">
171         <fo:block space-before="1.5em" space-after="1.5em" keep-together.within-page="50">
172             <xsl:apply-templates select="child::node()" />            
173         </fo:block>
174     </xsl:template>
175
176     <xsl:template match="wlml:v|wlml:vc">
177         <fo:block line-height="1.4"><xsl:apply-templates select="node()" /></fo:block>        
178     </xsl:template>
179     
180     <xsl:template match="wlml:vi">
181                  
182         <fo:block line-height="1.4">
183         <xsl:attribute name="text-indent">
184                 <xsl:choose>
185                         <xsl:when test="@size">
186                                 <xsl:value-of select="concat(xs:string(xs:integer(@size)), 'em')" />
187                         </xsl:when>
188                         <xsl:otherwise>1em</xsl:otherwise>                      
189                 </xsl:choose>           
190                 </xsl:attribute>
191                 <xsl:apply-templates select="node()" />
192         </fo:block>        
193     </xsl:template>
194
195 <!--
196     DRAMAT
197 -->
198
199 <xsl:template match="wlml:drama-line">        
200     <xsl:apply-templates select="child::node()" />       
201 </xsl:template>
202
203 <xsl:template match="wlml:drama-line/wlml:person">
204     <fo:block 
205         font-weight="bold"      
206         text-transform="uppercase"      
207         
208         keep-with-next.within-page="always"
209         keep-with-previous.within-page="0">
210         <xsl:apply-templates select="node()" />
211     </fo:block>
212 </xsl:template>
213
214 <xsl:template match="wlml:drama-line/wlml:stanza" priority="10">
215         <fo:block space-before="0.5em" space-after="1.5em" 
216                 keep-together.within-page="50"
217                 keep-with-previous.within-page="10" >           
218             <xsl:apply-templates select="child::node()" />
219         </fo:block>
220 </xsl:template>
221
222 <xsl:template match="wlml:person-list">
223 <fo:block keep-together.within-page="100"
224         break-before="page" break-after="page">
225 <fo:block text-transform="uppercase" 
226         font-weight="bold" font-size="150%"
227         line-height="1.4" space-after="2em">
228         <xsl:value-of select="wlml:caption" />
229 </fo:block>
230 <xsl:apply-templates select="wlml:person" />
231 </fo:block>
232 </xsl:template>
233
234 <xsl:template match="wlml:person">
235 <fo:block space-after="1em">
236         <xsl:apply-templates select="child::node()" />
237 </fo:block>
238 </xsl:template> 
239
240
241 <!--
242     Wyroznienia
243 -->
244     <xsl:template match="wlml:foreign">
245         <fo:inline font-style="italic">
246             <xsl:apply-templates select="node()" />
247         </fo:inline><fo:character character="&#8197;" />
248     </xsl:template>
249
250
251 <!--
252     Przypisy
253 -->
254 <xsl:template match="wlml:anchor">
255     <xsl:variable name="annot" select="/wlml:doc/wlml:annotations/wlml:annotation[@refs = current()/@id]" />
256     <fo:footnote>
257         <fo:inline vertical-align="super" font-size="0.75em"><xsl:number from="wlml:main-text|wlml:chapter" level="any" />) </fo:inline>
258         <!-- <fo:inline>* </fo:inline> -->
259         <fo:footnote-body>                      
260             <fo:block 
261                 font-weight="normal" font-style="normal"
262                 font-size="{concat($footnote-font-size, 'pt')}" 
263                 text-align="justify" text-indent="1.5em" space-after="1em">              
264             <xsl:number level="any" from="wlml:main-text|wlml:chapter"/>)<fo:character character="&#x2008;" />
265             
266             <xsl:if test="$annot/wlml:definition">
267             <fo:inline letter-spacing="0.1em"><xsl:apply-templates select="$annot/wlml:definition/node()" /></fo:inline>
268             <fo:character character="&#8197;" />&#x2014;<fo:character character="&#8197;" />
269             </xsl:if>
270             
271             <xsl:apply-templates select="$annot/wlml:body/node()" />            
272             </fo:block>                        
273         </fo:footnote-body>        
274     </fo:footnote>
275 </xsl:template>
276
277 <xsl:template match="*" />
278
279
280 <xsl:template match="text()">
281         <xsl:value-of select="wlf:enchance-for-print(.)" />
282 </xsl:template>
283
284 <xsl:function name="wlf:enchance-for-print">
285         <xsl:param name="text" />       
286         <xsl:value-of select="wlf:reduce-tokens(wlf:map-text-tokens(tokenize($text, '\s+')))" />        
287 </xsl:function>
288
289 <!--  Some usefull functions -->
290
291
292 <xsl:function name="wlf:map-text-tokens">
293         <xsl:param name="tokens" />
294         <xsl:for-each select="$tokens">
295                 <xsl:sequence select='                  
296                         replace(
297                         replace(
298                         replace(
299                         replace(
300                         replace(current(), 
301                                 "---", "&#x2014;"),
302                                 "--", "&#x2013;"),
303                                 ",,", "&#x201E;"),
304                                 """", "&#x201D;"),
305                                 "\.\.+", "&#x2026;") ' />                       
306         </xsl:for-each>         
307     </xsl:function>
308     
309     <xsl:function name="wlf:reduce-tokens">
310         <xsl:param name="tokens" />     
311         <xsl:for-each select="0 to count($tokens)">             
312                 <xsl:variable name="cur" select="$tokens[current()]" />
313                 <xsl:variable name="next" select="$tokens[current()+1]" />
314                 <xsl:choose>
315                         <xsl:when test="not($cur)" />
316                         <xsl:when test="$next = '&#x2014;'">
317                                 <xsl:value-of select="concat($cur, '&#8197;')" />                       
318                         </xsl:when>
319                         <xsl:when test="$cur = '&#x2014;'">                             
320                                 <xsl:value-of select="concat($cur, '&#8197;')" />                       
321                         </xsl:when>
322                         <xsl:when test="$next and string-length($cur) = 1">
323                                 <!--  non breaking space -->
324                                 <xsl:value-of select="concat($cur, '&#x00a0;')" />
325                         </xsl:when>                                             
326                         <xsl:when test="$next">
327                                 <xsl:value-of select="concat($cur, ' ')" />
328                         </xsl:when>                     
329                         <xsl:otherwise>
330                                 <xsl:value-of select="$cur" />
331                         </xsl:otherwise>                        
332                 </xsl:choose>
333         </xsl:for-each>
334     </xsl:function>
335
336 </xsl:stylesheet>
337