1 <?xml version="1.0" encoding="utf-8"?>
3 Copyright © 2009,2010 Łukasz Rekucki
5 This file is part of WL2PDF
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.
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.
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/>.
20 <xsl:stylesheet version="2.0"
21 xmlns="http://nowoczesnapolska.org.pl/ML/Lektury/1.1"
23 xmlns:xs="http://www.w3.org/2001/XMLSchema"
24 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
26 xmlns:wlf="http://wolnelektury.pl/functions"
28 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
29 xmlns:dc="http://purl.org/dc/elements/1.1/"
31 exclude-result-prefixes="wlf xsl xs"
34 <!-- Normalization Stylsheet for Wolne Lektury XML -->
35 <xsl:output method="xml" encoding="utf-8" indent="yes" />
36 <xsl:strip-space elements="rdf:RDF rdf:Description meta doc main-text strofa stanza drama-line" />
38 <xsl:variable name="punctuation" select="'.,;:!?'" />
40 <xsl:function name="wlf:fix-dialog-line">
41 <xsl:param name="text" />
43 <xsl:when test="starts-with($text, '---')">
44 <xsl:value-of select="wlf:normalize-text(substring-after($text, '---'))" />
47 <xsl:value-of select="$text" />
52 <xsl:function name="wlf:normalize-text">
53 <xsl:param name="text" />
54 <!-- The normalization step doesn't change the entities - it only normalizes whitespace -->
55 <xsl:value-of select="string-join(tokenize($text, '\s+'), ' ')" />
59 <!-- Main entry point -->
60 <xsl:template match="/">
63 <xsl:apply-templates select="//rdf:RDF" mode="meta"/>
66 <xsl:variable name="body" select="/utwor/*[local-name() = name()]" />
68 <main-text class="{name($body)}">
69 <xsl:apply-templates select="$body/node()" />
73 <xsl:apply-templates select="//pr|//pt|//pe|//pa" mode="annotations" />
78 <xsl:template match="strofa">
79 <xsl:element name="stanza" namespace="http://nowoczesnapolska.org.pl/ML/Lektury/1.1">
80 <!-- normalize verses -->
82 <xsl:when test="count(br) > 0">
83 <!-- First, collect all the tags up to first BR -->
84 <xsl:call-template name="verse">
85 <xsl:with-param name="verse-content" select="br[1]/preceding-sibling::node()" />
86 <xsl:with-param name="verse-type" select="br[1]/preceding-sibling::*[name() = 'wers_wciety' or name() = 'wers_akap' or name() = 'wers_cd'][1]" />
89 <!-- Collect the rest of verses -->
90 <xsl:for-each select="br">
91 <!-- Each BR tag "consumes" text after it -->
92 <xsl:variable name="lnum" select="count(preceding-sibling::br)" />
93 <xsl:call-template name="verse">
94 <xsl:with-param name="verse-content"
95 select="following-sibling::node()[count(preceding-sibling::br) = $lnum+1 and name() != 'br']" />
96 <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]" />
101 <!-- No BR's - collect the whole content -->
103 <xsl:call-template name="verse">
104 <xsl:with-param name="verse-content" select="child::node()" />
105 <xsl:with-param name="verse-type" select="wers_wciety|wers_akap|wers_cd[1]" />
113 <xsl:template name="verse">
114 <xsl:param name="verse-content" />
115 <xsl:param name="verse-type" />
118 <xsl:when test="not($verse-type)">
119 <xsl:element name="v" namespace="http://nowoczesnapolska.org.pl/ML/Lektury/1.1">
120 <xsl:apply-templates select="$verse-content" />
125 <xsl:apply-templates select="$verse-content" />
132 <xsl:template match="akap">
133 <xsl:element name="p">
134 <xsl:apply-templates select="@*|node()" />
138 <xsl:template match="akap_cd">
139 <xsl:element name="pc">
140 <xsl:apply-templates select="@*|node()" />
144 <xsl:template match="akap_dialog">
145 <xsl:element name="pd">
146 <xsl:variable name="prolog" select="./text()[1]" />
147 <xsl:value-of select="wlf:fix-dialog-line($prolog)" />
148 <xsl:apply-templates select="@*|*|text()[. != $prolog]" />
153 <xsl:template match="wers_cd">
154 <xsl:element name="vc">
155 <xsl:apply-templates select="@*|node()" />
159 <xsl:template match="wers_akap">
160 <xsl:element name="vi">
161 <xsl:attribute name="size">p</xsl:attribute>
162 <xsl:apply-templates select="@*|node()" />
166 <xsl:template match="wers_wciety">
167 <xsl:element name="vi">
169 <xsl:attribute name="size"><xsl:value-of select="@typ" /></xsl:attribute>
171 <xsl:apply-templates select="@*[name() != 'typ']|node()" />
175 <xsl:template match="zastepnik_wersu">
176 <xsl:element name="verse-skip">
178 <xsl:when test="starts-with(., '.')">
179 <xsl:attribute name="type">dot</xsl:attribute>
185 <!-- Przypisy i motywy -->
186 <xsl:template match="begin" />
187 <!-- <xsl:element name="mark">
188 <xsl:attribute name="starts">
189 <xsl:value-of select="substring(@id, 2)" />
191 <xsl:attribute name="themes">
192 <xsl:value-of select="following-sibling::motyw[1]/text()" />
197 <xsl:template match="motyw" />
199 <xsl:template match="end" />
201 <xsl:element name="mark">
202 <xsl:attribute name="ends">
203 <xsl:value-of select="substring(@id, 2)" />
208 <xsl:template match="pa|pe|pr|pt">
209 <!-- fetch the next text node -->
210 <xsl:variable name="tail" select="following-sibling::text()[1]" />
211 <xsl:variable name="tail-text" select="wlf:normalize-text($tail)" />
212 <xsl:variable name="first-char" select="substring($tail-text, 1, 1)" />
214 <xsl:if test="contains($punctuation, $first-char)">
215 <xsl:value-of select="$first-char" />
217 <anchor id="{generate-id(.)}" />
221 <xsl:template match="pa|pe|pr|pt" mode="annotations">
222 <annotation refs="{generate-id(.)}" type="{name(.)}">
223 <xsl:apply-templates select="@*" />
224 <xsl:variable name="text-node"
225 select="text()[not(matches(., '^\s*$'))][1]" />
227 <xsl:variable name="normalized-text" select="normalize-space($text-node)" />
229 <xsl:when test="slowo_obce[1] and slowo_obce[1] << $text-node">
230 <!-- <slowo_obce>Definition</slowo_obce> some stuff -->
232 <xsl:apply-templates select="child::slowo_obce[1]/node()" />
235 <xsl:value-of select="
236 if (starts-with($normalized-text, '---'))
238 wlf:normalize-text(substring-after($normalized-text, '---'))
242 <xsl:apply-templates select="$text-node/following-sibling::node()" />
245 <xsl:when test="not(contains($normalized-text, '---'))">
247 <xsl:value-of select="wlf:normalize-text($text-node)" />
248 <xsl:apply-templates select="$text-node/following-sibling::node()" />
253 <xsl:value-of select="wlf:normalize-text(substring-before($normalized-text, '---'))" />
256 <xsl:value-of select="wlf:normalize-text(substring-after($normalized-text, '---'))" />
257 <xsl:apply-templates select="$text-node/following-sibling::node()" />
266 <xsl:template match="autor_utworu">
267 <xsl:element name="author">
268 <xsl:apply-templates select="@*|node()" />
272 <xsl:template match="nazwa_utworu">
273 <xsl:element name="title">
274 <xsl:apply-templates select="@*|node()" />
278 <xsl:template match="naglowek_czesc">
280 <xsl:apply-templates select="@*|node()" />
284 <xsl:template match="naglowek_akt">
286 <xsl:apply-templates select="@*|node()" />
290 <xsl:template match="naglowek_scena">
292 <xsl:apply-templates select="@*|node()" />
296 <xsl:template match="podtytul">
298 <xsl:apply-templates select="@*|node()" />
302 <xsl:template match="srodtytul">
304 <xsl:apply-templates select="@*|node()" />
308 <!-- elementy dramatu -->
309 <xsl:template match="miejsce_czas">
310 <xsl:element name="time-and-date">
311 <xsl:apply-templates select="@*|node()" />
316 <xsl:template match="didaskalia|didask_tekst">
317 <xsl:element name="stage-directions">
318 <xsl:apply-templates select="@*|node()" />
322 <xsl:template match="motto">
323 <xsl:element name="motto">
324 <xsl:apply-templates select="@*|node()" />
326 <xsl:variable name="sign" select="following-sibling::*[1][name() = 'motto_podpis']" />
328 <xsl:apply-templates select="$sign/node()" />
333 <xsl:template match="motto_podpis[preceding-sibling::*[1][name() = 'motto']]" />
335 <xsl:template match="lista_osob">
337 <xsl:apply-templates select="@*|node()" />
341 <xsl:template match="naglowek_listy">
343 <xsl:apply-templates select="@*|node()" />
347 <xsl:template match="lista_osoba">
349 <xsl:apply-templates select="@*|node()" />
353 <!-- Odstępy i prześwity -->
354 <xsl:template match="sekcja_swiatlo">
358 <xsl:template match="sekcja_asterysk">
359 <vertical-space type="asterisk" />
362 <xsl:template match="sekcja_asterysk">
363 <vertical-space type="line" />
366 <!-- pozostałe elementy blokowe -->
367 <xsl:template match="dlugi_cytat">
369 <xsl:apply-templates select="@*|node()" />
373 <xsl:template match="poezja_cyt">
375 <xsl:apply-templates select="@*|node()" />
379 <xsl:template match="kwestia">
380 <xsl:variable name="person" select="preceding-sibling::*[1][name() = 'naglowek_osoba']" />
383 <xsl:apply-templates select="$person/node()" />
385 <xsl:apply-templates select="node()[. != $person]" />
389 <xsl:template match="naglowek_osoba[following-sibling::*[1][name() = 'kwestia']]" />
392 <xsl:template match="osoba">
393 <xsl:element name="person-ref">
394 <xsl:apply-templates select="@*|node()" />
398 <xsl:template match="slowo_obce">
399 <xsl:element name="foreign">
400 <xsl:apply-templates select="@*|node()" />
404 <xsl:template match="wyroznienie">
405 <xsl:element name="em">
406 <xsl:apply-templates select="@*|node()" />
410 <xsl:template match="mat">
411 <xsl:element name="math">
412 <xsl:apply-templates select="@*|node()" />
416 <!-- oznaczenie tytulu innego utworu, wymienionego w tym -->
417 <xsl:template match="tytul_dziela">
418 <xsl:element name="book-ref">
419 <xsl:apply-templates select="@*|node()" />
423 <xsl:template match="extra">
424 <xsl:element name="comment">
425 <xsl:apply-templates select="@*|node()" />
429 <xsl:template match="uwaga">
430 <xsl:element name="edit-comment">
431 <xsl:apply-templates select="@*|node()" />
435 <!-- Copy attributes -->
436 <xsl:template match="@*|comment()">
440 <!-- Inside RDF meta-data, leave the text unchanged -->
441 <xsl:template match="rdf:RDF//text()">
442 <xsl:value-of select="." />
445 <!-- Normalize text in other nodes -->
446 <xsl:template match="text()">
447 <xsl:variable name="normalized" select="wlf:normalize-text(.)" />
448 <xsl:variable name="first-char" select="substring($normalized, 1, 1)" />
449 <xsl:variable name="siblings-before" select="preceding-sibling::pr|preceding-sibling::pa|preceding-sibling::pe|preceding-sibling::pt|preceding-sibling::text()" />
451 <xsl:when test="contains($punctuation, $first-char) and $siblings-before[last()]">
452 <xsl:value-of select="substring($normalized, 2)" />
455 <xsl:value-of select="$normalized" />
460 <!-- Ignoruj RDF poza meta -->
461 <xsl:template match="rdf:*|dc:*" />
463 <xsl:template match="@*|node()" mode="meta">
465 <xsl:apply-templates select="@*|node()" mode="meta" />
469 <!-- Warn about non-matched elements -->
470 <xsl:template match="node()" priority="-1">
472 <xsl:copy-of select="." />