Fixed to run and pass all tests.
[librarian.git] / librarian / xslt / normalize.xslt
1 <?xml version="1.0" encoding="utf-8"?>
2 <!--
3 #
4 #    This file is part of Librarian.
5 #
6 #    Copyright © 2008,2009,2010 Fundacja Nowoczesna Polska <fundacja@nowoczesnapolska.org.pl>
7 #    
8 #    For full list of contributors see AUTHORS file. 
9 #
10 #    This program is free software: you can redistribute it and/or modify
11 #    it under the terms of the GNU Affero General Public License as published by
12 #    the Free Software Foundation, either version 3 of the License, or
13 #    (at your option) any later version.
14 #
15 #    This program is distributed in the hope that it will be useful,
16 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
17 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 #    GNU Affero General Public License for more details.
19 #
20 #    You should have received a copy of the GNU Affero General Public License
21 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 #
23 -->
24 <xsl:stylesheet version="1.0"
25     xmlns="http://nowoczesnapolska.org.pl/ML/Lektury/1.1"
26         
27     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
28     xmlns:wlf="http://wolnelektury.pl/functions"
29
30     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
31     xmlns:dc="http://purl.org/dc/elements/1.1/"
32
33     exclude-result-prefixes="wlf xsl"
34 >
35
36     <!-- Normalization Stylsheet for Wolne Lektury XML -->
37     <xsl:output method="xml" encoding="utf-8" indent="yes" />
38      
39     <xsl:strip-space elements="rdf:RDF rdf:Description meta doc main-text strofa stanza drama-line wlml:*" />
40
41     <xsl:param name="normalize-text" select="boolean(1)" />
42
43     <!-- Main entry point -->
44     <xsl:template match="/">
45         <doc>
46             <meta>
47                 <xsl:apply-templates select="//rdf:RDF" mode="meta"/>
48             </meta>
49
50             <xsl:variable name="body" select="/utwor/*[local-name() = name()]" />
51
52             <main-text class="{name($body)}">
53                 <xsl:apply-templates select="$body/node()" />
54             </main-text>
55
56             <annotations>
57                 <xsl:apply-templates select="//pr|pt|pe|pa" mode="annotations" />              
58             </annotations>
59         </doc>
60     </xsl:template>    
61
62     <xsl:template match="strofa">
63         <xsl:element name="stanza" namespace="http://nowoczesnapolska.org.pl/ML/Lektury/1.1">
64             <!-- normalize verses -->
65             <xsl:choose>
66                 <xsl:when test="count(br) > 0">
67                     <!-- First, collect all the tags up to first BR -->
68                     <xsl:call-template name="verse">
69                         <xsl:with-param name="verse-content" select="br[1]/preceding-sibling::node()" />
70                         <xsl:with-param name="verse-type" select="br[1]/preceding-sibling::*[name() = 'wers_wciety' or name() = 'wers_akap' or name() = 'wers_cd'][1]" />
71                     </xsl:call-template>
72
73                     <!-- Collect the rest of verses -->
74                     <xsl:for-each select="br">
75                                 <!-- Each BR tag "consumes" text after it -->
76                         <xsl:variable name="lnum" select="count(preceding-sibling::br)" />
77                         <xsl:call-template name="verse">
78                             <xsl:with-param name="verse-content"
79                                 select="following-sibling::node()[count(preceding-sibling::br) = $lnum+1 and name() != 'br']" />
80                             <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]" />
81                         </xsl:call-template>
82                     </xsl:for-each>
83                 </xsl:when>
84
85                 <!-- No BR's - collect the whole content -->
86                 <xsl:otherwise>
87                     <xsl:call-template name="verse">
88                         <xsl:with-param name="verse-content" select="child::node()" />
89                         <xsl:with-param name="verse-type" select="wers_wciety|wers_akap|wers_cd[1]" />
90                     </xsl:call-template>
91                 </xsl:otherwise>
92
93             </xsl:choose>
94         </xsl:element>
95     </xsl:template>
96
97     <xsl:template name="verse">
98         <xsl:param name="verse-content" />
99         <xsl:param name="verse-type" />
100
101         <xsl:choose>
102             <xsl:when test="not($verse-type)">
103                 <xsl:element name="v" namespace="http://nowoczesnapolska.org.pl/ML/Lektury/1.1">
104                     <xsl:apply-templates select="$verse-content" />
105                 </xsl:element>
106             </xsl:when>
107
108             <xsl:otherwise>
109                 <xsl:apply-templates select="$verse-content" />
110             </xsl:otherwise>
111         </xsl:choose>
112     </xsl:template>
113
114
115     <!-- akapity -->
116     <xsl:template match="akap">
117         <xsl:element name="p">
118             <xsl:apply-templates select="@*|node()" />
119         </xsl:element>
120     </xsl:template>
121
122     <xsl:template match="akap_cd">
123         <xsl:element name="pc">
124             <xsl:apply-templates select="@*|node()" />
125         </xsl:element>
126     </xsl:template>
127
128     <xsl:template match="akap_dialog">
129         <xsl:element name="pd">
130             <xsl:variable name="prolog" select="./text()[1]" />            
131             <xsl:value-of select="wlf:fix-dialog-line($prolog)" />
132             <xsl:apply-templates select="@*|*|text()[. != $prolog]" />
133         </xsl:element>
134     </xsl:template>
135
136     <!-- wersy -->
137     <xsl:template match="wers_cd">
138         <xsl:element name="vc">
139             <xsl:apply-templates select="@*|node()" />
140         </xsl:element>
141     </xsl:template>
142
143     <xsl:template match="wers_akap">
144         <xsl:element name="vi">
145             <xsl:attribute name="size">p</xsl:attribute>
146             <xsl:apply-templates select="@*|node()" />
147         </xsl:element>
148     </xsl:template>
149
150     <xsl:template match="wers_wciety">
151         <xsl:element name="vi">
152             <xsl:if test="@typ">
153             <xsl:attribute name="size"><xsl:value-of select="@typ" /></xsl:attribute>
154             </xsl:if>
155             <xsl:apply-templates select="@*[name() != 'typ']|node()" />
156         </xsl:element>
157     </xsl:template>
158
159     <xsl:template match="zastepnik_wersu">
160         <xsl:element name="verse-skip">
161             <xsl:choose>
162                 <xsl:when test="starts-with(., '.')">
163                     <xsl:attribute name="type">dot</xsl:attribute>
164                 </xsl:when>
165             </xsl:choose> 
166         </xsl:element>
167     </xsl:template>
168
169     <!-- Przypisy i motywy -->
170     <xsl:template match="begin">
171         <xsl:element name="mark">
172             <xsl:attribute name="starts">
173                 <xsl:value-of select="substring(@id, 2)" />
174             </xsl:attribute>
175             <xsl:attribute name="themes">
176                 <xsl:value-of select="following-sibling::motyw[1]/text()" />
177             </xsl:attribute>
178         </xsl:element>
179     </xsl:template>
180
181     <xsl:template match="motyw" />
182
183     <xsl:template match="end">
184         <xsl:element name="mark">
185             <xsl:attribute name="ends">
186                 <xsl:value-of select="substring(@id, 2)" />
187             </xsl:attribute>
188         </xsl:element>
189     </xsl:template>
190
191     <xsl:template match="pa|pe|pr|pt">
192         <mark id="{generate-id(.)}" />
193     </xsl:template>
194
195
196     <xsl:template match="pa|pe|pr|pt" mode="annotations">
197         <annotation refs="{generate-id(.)}" type="{name(.)}">
198             <xsl:apply-templates select="@*|node()" />
199         </annotation>
200     </xsl:template>
201
202
203     <!-- Tytuły -->
204     <xsl:template match="autor_utworu">
205         <xsl:element name="author">
206             <xsl:apply-templates select="@*|node()" />
207         </xsl:element>
208     </xsl:template>
209
210     <xsl:template match="nazwa_utworu">
211         <xsl:element name="title">
212             <xsl:apply-templates select="@*|node()" />
213         </xsl:element>
214     </xsl:template>
215
216     <xsl:template match="naglowek_czesc">
217         <chapter>
218             <xsl:apply-templates select="@*|node()" />
219         </chapter>
220     </xsl:template>
221
222     <xsl:template match="naglowek_akt">
223         <act>
224             <xsl:apply-templates select="@*|node()" />
225         </act>
226     </xsl:template>
227
228     <xsl:template match="naglowek_scena">
229         <scene>
230             <xsl:apply-templates select="@*|node()" />
231         </scene>
232     </xsl:template>
233
234     <xsl:template match="podtytul">
235         <second-title>
236             <xsl:apply-templates select="@*|node()" />
237         </second-title>
238     </xsl:template>
239
240     <xsl:template match="srodtytul">
241         <part-title>
242             <xsl:apply-templates select="@*|node()" />
243         </part-title>
244     </xsl:template>
245
246     <!-- elementy dramatu -->
247     <xsl:template match="miejsce_czas">
248         <xsl:element name="time-and-date">
249             <xsl:apply-templates select="@*|node()" />
250         </xsl:element>
251     </xsl:template>
252
253
254     <xsl:template match="didaskalia|didask_tekst">
255         <xsl:element name="stage-directions">
256             <xsl:apply-templates select="@*|node()" />
257         </xsl:element>
258     </xsl:template>
259
260     <xsl:template match="motto">
261         <xsl:element name="motto">
262             <xsl:apply-templates select="@*|node()" />
263         
264         <xsl:variable name="sign" select="following-sibling::*[1][name() = 'motto_podpis']" />
265         <signature>
266             <xsl:apply-templates select="$sign/node()" />
267         </signature>
268         </xsl:element>
269     </xsl:template>
270
271     <xsl:template match="motto_podpis[preceding-sibling::*[1][name() = 'motto']]" />
272         
273     <xsl:template match="lista_osob">
274         <person-list>
275             <xsl:apply-templates select="@*|node()" />
276         </person-list>
277     </xsl:template>
278
279     <xsl:template match="naglowek_listy">
280         <caption>
281             <xsl:apply-templates select="@*|node()" />
282         </caption>
283     </xsl:template>
284
285     <xsl:template match="lista_osoba">
286         <person>
287             <xsl:apply-templates select="@*|node()" />
288         </person>
289     </xsl:template>
290
291     <!-- Odstępy i prześwity -->
292     <xsl:template match="sekcja_swiatlo">
293         <vertical-space />
294     </xsl:template>
295     
296     <xsl:template match="sekcja_asterysk">
297         <vertical-space type="asterisk" />
298     </xsl:template>
299
300     <xsl:template match="sekcja_asterysk">
301         <vertical-space type="line" />
302     </xsl:template>
303
304     <!-- pozostałe elementy blokowe -->
305     <xsl:template match="dlugi_cytat">
306         <block-quote>
307             <xsl:apply-templates select="@*|node()" />
308         </block-quote>`
309     </xsl:template>
310
311     <xsl:template match="poezja_cyt">
312         <block-quote>
313             <xsl:apply-templates select="@*|node()" />
314         </block-quote>`
315     </xsl:template>
316
317     <xsl:template match="kwestia">
318         <xsl:variable name="person" select="preceding-sibling::*[1][name() = 'naglowek_osoba']" />
319         <drama-line>
320             <person>
321                 <xsl:apply-templates select="$person/node()" />
322             </person>
323             <xsl:apply-templates select="node()[. != $person]" />
324         </drama-line>
325     </xsl:template>
326
327     <xsl:template match="naglowek_osoba[following-sibling::*[1][name() = 'kwestia']]" />
328         
329     <!-- Inne -->
330     <xsl:template match="osoba">
331         <xsl:element name="person-ref">
332             <xsl:apply-templates select="@*|node()" />
333         </xsl:element>
334     </xsl:template>
335
336     <xsl:template match="slowo_obce">
337         <xsl:element name="df">
338             <xsl:apply-templates select="@*|node()" />
339         </xsl:element>
340     </xsl:template>
341
342     <xsl:template match="wyroznienie">
343         <xsl:element name="em">
344             <xsl:apply-templates select="@*|node()" />
345         </xsl:element>
346     </xsl:template>
347
348     <xsl:template match="mat">
349         <xsl:element name="math">
350             <xsl:apply-templates select="@*|node()" />
351         </xsl:element>
352     </xsl:template>
353
354     <!-- oznaczenie tytulu innego utworu, wymienionego w tym -->
355     <xsl:template match="tytul_dziela">
356         <xsl:element name="book-ref">
357             <xsl:apply-templates select="@*|node()" />
358         </xsl:element>
359     </xsl:template>
360
361     <xsl:template match="extra">
362         <xsl:element name="comment">
363             <xsl:apply-templates select="@*|node()" />
364         </xsl:element>
365     </xsl:template>
366
367     <xsl:template match="uwaga">
368         <xsl:element name="edit-comment">
369             <xsl:apply-templates select="@*|node()" />
370         </xsl:element>
371     </xsl:template>
372
373     <!-- Copy attributes -->
374     <xsl:template match="@*|comment()">
375         <xsl:copy />
376     </xsl:template>    
377
378     <!-- Inside RDF meta-data, leave the text unchanged -->
379     <xsl:template match="rdf:RDF//text()">
380         <xsl:value-of select="." />
381     </xsl:template>
382
383     <!-- Normalize text in other nodes -->
384     <xsl:template match="text()">
385         <xsl:choose>
386             <xsl:when test="$normalize-text">
387                 <xsl:value-of select="wlf:normalize-text(.)" />
388             </xsl:when>
389             <xsl:otherwise>
390                 <xsl:value-of select="." />
391             </xsl:otherwise>
392         </xsl:choose>
393     </xsl:template>
394
395     <!-- Ignoruj RDF poza meta -->
396     <xsl:template match="rdf:*|dc:*" />
397    
398     <xsl:template match="@*|node()" mode="meta">
399         <xsl:copy>
400             <xsl:apply-templates match="@*|node()" mode="meta" />
401         </xsl:copy>
402     </xsl:template>
403
404     <!-- Warn about non-matched elements -->
405     <xsl:template match="node()">
406         <xsl:message>
407             <xsl:text>Nieprzetworzony węzeł:</xsl:text>
408             <xsl:value-of select="." />           
409         </xsl:message>
410         <unparsed-node>
411             <xsl:copy-of select="." />
412         </unparsed-node>
413     </xsl:template>
414     
415 </xsl:stylesheet>