fixes for edge cases
[librarian.git] / src / librarian / xslt / wl2html_base.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
9     version="1.0"
10
11     xmlns="http://www.w3.org/1999/xhtml"
12     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
13     xmlns:wl="http://wolnelektury.pl/functions"
14
15     exclude-result-prefixes="wl" >
16
17     <xsl:variable name="config" select="document('config.xml')" />
18
19     <xsl:output method="xml"
20         encoding="utf-8"
21         indent="yes"
22         omit-xml-declaration = "yes" />
23
24     <!--
25         Dokument ten opisuje podstawowe przekształcenia potrzebne
26      do zamiany dokumentu WLML 1.0 na poprawnie sformatowany
27      dokument XHMTL.
28
29     -->
30
31     <xsl:template name="generic-attributes">
32         <xsl:param name="element" />
33         <xsl:param name="mypath" />
34         <xsl:variable name="tag" select="name($element)" />
35
36         <xsl:if test="$with-paths">
37             <xsl:attribute name="x-pointer">
38                 <xsl:value-of select="$mypath" />
39             </xsl:attribute>
40         </xsl:if>
41
42         <xsl:if test="$config//editable/*[name() = $tag]">
43             <xsl:attribute name="x-editable">editable</xsl:attribute>
44         </xsl:if>
45
46         <xsl:attribute name="class">
47             <xsl:value-of select="$tag"/>
48         </xsl:attribute>
49     </xsl:template>
50
51     <xsl:template name="generic-descent">
52         <xsl:param name="element" />
53         <xsl:param name="mypath" />
54         <xsl:param name="mixed" />
55
56         <xsl:for-each select="child::node()">
57             <xsl:apply-templates select="." mode="element-tag">
58                 <xsl:with-param name="offset" select="count(preceding-sibling::*)" />
59                 <xsl:with-param name="parent-path" select="$mypath" />
60                 <xsl:with-param name="mixed" select="$mixed" />
61             </xsl:apply-templates>
62         </xsl:for-each>
63     </xsl:template>
64
65     <xsl:template name="generic-content">
66         <xsl:param name="element" />
67         <xsl:param name="mypath" />
68         <xsl:param name="mixed" />
69
70         <xsl:call-template name="generic-attributes">
71             <xsl:with-param name="element" select="$element" />
72             <xsl:with-param name="mypath" select="$mypath" />
73         </xsl:call-template>
74
75         <xsl:call-template name="generic-descent">
76             <xsl:with-param name="element" select="$element" />
77             <xsl:with-param name="mypath" select="$mypath" />
78             <xsl:with-param name="mixed" select="$mixed" />
79         </xsl:call-template>
80     </xsl:template>
81
82     <!-- Generyczne szablony -->
83     <xsl:template name="generic" >
84         <xsl:param name="element" />
85         <xsl:param name="mypath" />
86         <xsl:param name="offset" />
87
88         <!-- <xsl:param name="parent-type" select="'block'" /> -->
89
90         <xsl:variable name="tag" select="name($element)" />
91         <xsl:variable name="group" select="$config//types/*[@element and child::*[local-name() = $tag]]" />
92
93         <xsl:choose>
94             <!-- ignore namespaced elements -->
95             <xsl:when test="namespace-uri()" />
96             <xsl:when test="$group/@element">
97
98                 <xsl:element name="{$group/@element}" namespace="http://www.w3.org/1999/xhtml">
99                     <xsl:apply-templates select="$element" mode="element-content" >
100                         <xsl:with-param name="mypath" select="$mypath" />
101                         <xsl:with-param name="mixed" select="boolean($group/@mixed)" />
102                     </xsl:apply-templates>
103                 </xsl:element>
104             </xsl:when>
105             <xsl:otherwise />
106         </xsl:choose>
107
108     </xsl:template>
109
110     <!--
111         Tagi niestandardowe
112     -->
113
114     <xsl:template match="pr|pa|pe|pt" mode="element-tag">
115         <a href="#annotation-{generate-id(.)}"><span class="annotation"/></a><a name="anchor-{generate-id(.)}" />
116     </xsl:template>
117
118     <xsl:template match="dlugi_cytat|poezja_cyt" mode="element-tag">
119         <xsl:param name="offset" />
120         <xsl:param name="parent-path" />
121         <xsl:variable name="mypath"
122             select="concat($parent-path, '/', name(), '[', string($offset),']')" />
123
124         <xsl:element name="blockquote" >
125             <xsl:call-template name="generic-attributes">
126                 <xsl:with-param name="element" select="current()" />
127                 <xsl:with-param name="mypath" select="$mypath" />
128             </xsl:call-template>
129             <xsl:call-template name="generic-descent">
130                 <xsl:with-param name="element" select="current()" />
131                 <xsl:with-param name="mypath" select="$mypath" />
132                 <xsl:with-param name="mixed" select="true" />
133             </xsl:call-template>
134         </xsl:element>
135     </xsl:template>
136
137
138     <xsl:template match="lista_osob" mode="element-tag">
139         <xsl:param name="offset" />
140         <xsl:param name="parent-path" />
141         <xsl:variable name="mypath"
142             select="concat($parent-path, '/', name(), '[', string($offset),']')" />
143
144         <xsl:element name="div" >
145             <xsl:call-template name="generic-attributes">
146                 <xsl:with-param name="element" select="current()" />
147                 <xsl:with-param name="mypath" select="$mypath" />
148             </xsl:call-template>
149
150             <xsl:apply-templates select="./naglowek-listy" mode="element-tag" />
151             <ul>
152                 <xsl:for-each select="./lista_osoba">
153                     <xsl:apply-templates select="." mode="element-tag">
154                         <xsl:with-param name="offset" select="count(preceding-sibling::*)" />
155                         <xsl:with-param name="parent-path" select="$mypath" />
156                         <xsl:with-param name="mixed" select="false" />
157                     </xsl:apply-templates>
158                 </xsl:for-each>
159             </ul>
160         </xsl:element>
161     </xsl:template>
162
163     <xsl:template match="lista_osoba" mode="element-tag">
164         <xsl:param name="offset" />
165         <xsl:param name="parent-path" />
166         <xsl:variable name="mypath"
167             select="concat($parent-path, '/', name(), '[', string($offset),']')" />
168
169         <xsl:element name="li" >
170             <xsl:call-template name="generic-attributes">
171                 <xsl:with-param name="element" select="current()" />
172                 <xsl:with-param name="mypath" select="$mypath" />
173             </xsl:call-template>
174             <xsl:call-template name="generic-descent">
175                 <xsl:with-param name="element" select="current()" />
176                 <xsl:with-param name="mypath" select="$mypath" />
177                 <xsl:with-param name="mixed" select="true" />
178             </xsl:call-template>
179         </xsl:element>
180     </xsl:template>
181
182     <xsl:template match="separator_linia" mode="element-tag">
183         <xsl:param name="offset" />
184         <xsl:param name="parent-path" />
185         <xsl:variable name="mypath"
186             select="concat($parent-path, '/', name(), '[', string($offset),']')" />
187
188         <xsl:element name="hr" >
189             <xsl:call-template name="generic-attributes">
190                 <xsl:with-param name="element" select="current()" />
191                 <xsl:with-param name="mypath" select="$mypath" />
192             </xsl:call-template>
193         </xsl:element>
194     </xsl:template>
195
196     <xsl:template match="sekcja_swiatlo" mode="element-tag">
197         <xsl:param name="offset" />
198         <xsl:param name="parent-path" />
199         <xsl:variable name="mypath"
200             select="concat($parent-path, '/', name(), '[', string($offset),']')" />
201
202         <xsl:element name="br" >
203             <xsl:call-template name="generic-attributes">
204                 <xsl:with-param name="element" select="current()" />
205                 <xsl:with-param name="mypath" select="$mypath" />
206             </xsl:call-template>
207         </xsl:element>
208     </xsl:template>
209
210     <xsl:template match="sekcja_asterysk" mode="element-tag">
211         <xsl:param name="offset" />
212         <xsl:param name="parent-path" />
213         <xsl:variable name="mypath"
214             select="concat($parent-path, '/', name(), '[', string($offset),']')" />
215
216         <xsl:element name="p" >
217             <xsl:call-template name="generic-attributes">
218                 <xsl:with-param name="element" select="current()" />
219                 <xsl:with-param name="mypath" select="$mypath" />
220             </xsl:call-template>
221             *
222         </xsl:element>
223     </xsl:template>
224
225     <xsl:template match="zastepnik_wersu|wers_akap|wers_cd|wers_wciety" mode="element-tag">
226         <xsl:param name="offset" />
227         <xsl:param name="parent-path" />
228
229         <xsl:variable name="mypath"
230             select="concat($parent-path, '/', name(), '[',string($offset),']')" />
231
232         <xsl:call-template name="generic-descent">
233             <xsl:with-param name="element" select="current()" />
234             <xsl:with-param name="mypath" select="$mypath" />
235             <xsl:with-param name="mixed" select="boolean(1)" />
236         </xsl:call-template>
237     </xsl:template>
238
239     <!-- strofy -->
240     <xsl:template match="strofa" mode="element-tag">
241         <xsl:param name="offset" />
242         <xsl:param name="parent-path" />
243
244         <xsl:variable name="mypath"
245             select="concat($parent-path, '/', name(), '[', string($offset),']')" />
246
247         <xsl:element name="div" >
248             <xsl:call-template name="generic-attributes">
249                 <xsl:with-param name="element" select="current()" />
250                 <xsl:with-param name="mypath" select="$mypath" />
251             </xsl:call-template>
252
253             <xsl:choose>
254                 <xsl:when test="count(br) > 0">
255                     <xsl:call-template name="verse">
256                         <xsl:with-param name="verse-content" select="br[1]/preceding-sibling::text() | br[1]/preceding-sibling::node()" />
257                         <xsl:with-param name="verse-type" select="br[1]/preceding-sibling::*[name() = 'wers_wciety' or name() = 'wers_akap' or name() = 'wers_cd'][1]" />
258                         <xsl:with-param name="mypath" select="$mypath" />
259                     </xsl:call-template>
260                     <xsl:for-each select="br">
261                                 <!-- Each BR tag "consumes" text after it -->
262                         <xsl:variable name="lnum" select="count(preceding-sibling::br)" />
263                         <xsl:call-template name="verse">
264                             <xsl:with-param name="verse-content"
265                                 select="following-sibling::text()[count(preceding-sibling::br) = $lnum+1] | following-sibling::node()[count(preceding-sibling::br) = $lnum+1]" />
266                             <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]" />
267                             <xsl:with-param name="mypath" select="$mypath" />
268                         </xsl:call-template>
269                     </xsl:for-each>
270                 </xsl:when>
271                 <xsl:otherwise>
272                     <xsl:call-template name="verse">
273                         <xsl:with-param name="verse-content" select="child::node()" />
274                         <xsl:with-param name="verse-type" select="wers_wciety|wers_akap|wers_cd[1]" />
275                         <xsl:with-param name="mypath" select="$mypath" />
276                     </xsl:call-template>
277                 </xsl:otherwise>
278             </xsl:choose>
279         </xsl:element>
280     </xsl:template>
281
282     <xsl:template name="verse">
283         <xsl:param name="verse-content" />
284         <xsl:param name="verse-type" />
285         <xsl:param name="mypath" />
286
287         <xsl:element name="p">
288             <xsl:attribute name="class">
289                 <xsl:value-of select="name($verse-type)" />
290             </xsl:attribute>
291             <xsl:for-each select="$verse-content">
292                 <xsl:apply-templates select="." mode="element-tag">
293                     <xsl:with-param name="offset" select="count(preceding-sibling::*)" />
294                     <xsl:with-param name="parent-path" select="$mypath" />
295                     <xsl:with-param name="mixed" select="boolean(1)" />
296                 </xsl:apply-templates>
297             </xsl:for-each>
298         </xsl:element>
299     </xsl:template>
300
301
302 <!-- default content processing -->
303     <xsl:template match="*" mode="element-content">
304         <xsl:param name="mypath" />
305         <xsl:param name="mixed" />
306
307         <xsl:call-template name="generic-content">
308             <xsl:with-param name="element" select="current()"/>
309             <xsl:with-param name="mypath" select="$mypath"/>
310             <xsl:with-param name="mixed" select="$mixed"/>
311         </xsl:call-template>
312     </xsl:template>
313
314     <xsl:template match="*" mode="element-tag" >
315         <xsl:param name="offset" />
316         <xsl:param name="parent-path" />
317         <xsl:param name="mixed" />
318
319         <xsl:variable name="mypath"
320             select="concat($parent-path, '/', name(), '[', string($offset),']')" />
321
322         <xsl:call-template name="generic">
323             <xsl:with-param name="element" select="current()" />
324             <xsl:with-param name="offset" select="$offset" />
325             <xsl:with-param name="mypath" select="$mypath" />
326             <xsl:with-param name="mixed" select="$mixed"/>
327         </xsl:call-template>
328     </xsl:template>
329
330     <xsl:template match="text()" mode="element-tag">
331         <xsl:param name="mixed" />
332
333         <xsl:choose>
334
335             <xsl:when test="not($mixed)">
336                 <xsl:choose>
337                     <xsl:when test="not(normalize-space(.))" />
338                     <xsl:when test="normalize-space(.) = '&#xfeff;'"/>
339
340                     <xsl:otherwise>
341                         <div class="parse-warning">
342                             <p class="message">Uwaga! Tekst poza paragrafem</p>
343                             <p>#<xsl:copy-of select="." />#</p>
344                         </div>
345                     </xsl:otherwise>
346                 </xsl:choose>
347             </xsl:when>
348
349             <xsl:otherwise>
350                 <xsl:value-of select="wl:substitute_entities(.)">
351                     <xsl:fallback>
352                         <xsl:value-of select="." />
353                     </xsl:fallback>
354                 </xsl:value-of>
355             </xsl:otherwise>
356
357         </xsl:choose>
358
359     </xsl:template>
360
361     <xsl:template match="node()" />
362
363 </xsl:stylesheet>