XSLT-2.0-Code in »epub.xsl« zum Projekt »epubMinFlow«

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <!-- XSLT 2.0-Stylesheet epub.xsl zum Projekt epubMinFlow - 04/2010
  3      by Dr. Thomas Meinike - http://datenverdrahten.de/epubMinFlow/
  4      Version 1.5 - 2011-08-19 -->
  5 <xsl:stylesheet version="2.0"
  6   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  7   xmlns:fn="http://www.w3.org/2005/xpath-functions"
  8   xmlns:xs="http://www.w3.org/2001/XMLSchema"
  9   xmlns="http://www.w3.org/1999/xhtml"
 10   exclude-result-prefixes="fn xs">
 11 
 12 
 13   <!-- Globale Vorgaben - variable IDs, Dateinamen und Pfade -->
 14   <xsl:variable name="bookid" select="'BookId'"/>
 15   <xsl:variable name="contentfile" select="'content.opf'"/>
 16   <xsl:variable name="tocfile" select="'toc.ncx'"/>
 17   <xsl:variable name="epubdir" select="'epub'"/>
 18   <xsl:variable name="opsdir" select="'OPS'"/>
 19   <xsl:variable name="cssdir" select="'style'"/>
 20   <xsl:variable name="imgdir" select="'bilder'"/>
 21   <xsl:variable name="fontdir" select="'fonts'"/>
 22   <xsl:variable name="htmldir" select="'html'"/>
 23   <xsl:variable name="coverid" select="'buchcover'"/>
 24   <xsl:variable name="tocid" select="'buchinhalt'"/>
 25   <xsl:variable name="tocpage" select="'inhalt.html'"/>
 26   <xsl:variable name="css" select="/buch/dateien/datei[@id='stylesheet']/@name"/>
 27   <xsl:variable name="ade" select="/buch/dateien/datei[@id='page-template']/@name"/>
 28 
 29 
 30   <!-- Ausgabeformate zur Dateierzeugung über xsl:result-document -->
 31   <xsl:output name="stdxml" method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
 32 
 33   <xsl:output name="tocncx" method="xml" version="1.0" encoding="UTF-8" indent="yes"
 34     doctype-public="-//NISO//DTD ncx 2005-1//EN" doctype-system="http://www.daisy.org/z3986/2005/ncx-2005-1.dtd"/>
 35 
 36   <xsl:output name="xhtml11" method="xhtml" version="1.1" encoding="UTF-8" media-type="application/xhtml+xml" indent="yes"
 37     doctype-public="-//W3C//DTD XHTML 1.1//EN" doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"/>
 38 
 39 
 40   <xsl:template match="buch">
 41     <!-- EPUB-Struktur: container.xml in META_INF (beide Namen sind obligatorisch) -->
 42     <xsl:result-document href="{$epubdir}/META-INF/container.xml" format="stdxml">
 43       <container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
 44 
 45         <rootfiles>
 46           <rootfile full-path="{$opsdir}/{$contentfile}" media-type="application/oebps-package+xml"/>
 47         </rootfiles>
 48 
 49       </container>
 50     </xsl:result-document>
 51 
 52 
 53     <!-- EPUB-Struktur: content.opf in OPS (beide Namen sind variabel) -->
 54     <xsl:result-document href="{$epubdir}/{$opsdir}/{$contentfile}" format="stdxml">
 55       <package xmlns="http://www.idpf.org/2007/opf" unique-identifier="{$bookid}" version="2.0">
 56 
 57         <metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
 58           <!-- Pflichtangaben -->
 59           <dc:identifier id="{$bookid}"><xsl:value-of select="metadaten/ident"/></dc:identifier>
 60           <dc:title><xsl:value-of select="metadaten/titel"/></dc:title>
 61           <dc:language><xsl:value-of select="if(metadaten/sprache) then metadaten/sprache else 'en'"/></dc:language>
 62 
 63           <!-- optionale Angaben -->
 64           <xsl:if test="metadaten/autor">
 65             <dc:creator><xsl:value-of select="metadaten/autor"/></dc:creator>
 66           </xsl:if>
 67           <xsl:if test="metadaten/genre">
 68             <dc:subject><xsl:value-of select="metadaten/genre"/></dc:subject>
 69           </xsl:if>
 70           <xsl:if test="metadaten/datum">
 71             <dc:date><xsl:value-of select="metadaten/datum"/></dc:date>
 72           </xsl:if>
 73           <xsl:if test="metadaten/herausgeber">
 74             <dc:publisher><xsl:value-of select="metadaten/herausgeber"/></dc:publisher>
 75           </xsl:if>
 76           <xsl:if test="metadaten/beschreibung">
 77             <dc:description><xsl:value-of select="metadaten/beschreibung"/></dc:description>
 78           </xsl:if>
 79 
 80           <meta name="cover" content="coverimage"/>
 81         </metadata>
 82 
 83         <manifest>
 84           <!-- Basis- und Zusatzdateien: NCX-TOC, CSS, Titelbild, ... -->
 85           <item id="toc" href="{$tocfile}" media-type="application/x-dtbncx+xml"/>
 86 
 87           <xsl:for-each select="dateien/datei">
 88             <item id="{@id}">
 89               <xsl:attribute name="href">
 90                 <xsl:choose>
 91                   <xsl:when test="fn:contains(@name,'.css')"><xsl:value-of select="fn:concat($cssdir,'/',@name)"/></xsl:when>
 92                   <xsl:when test="fn:contains(@name,'.htm')"><xsl:value-of select="fn:concat($htmldir,'/',@name)"/></xsl:when>
 93                   <xsl:when test="fn:contains(@name,'.gif') or fn:contains(@name,'.jpg') or fn:contains(@name,'.png') or
 94                                   fn:contains(@name,'.svg')"><xsl:value-of select="fn:concat($imgdir,'/',@name)"/></xsl:when>
 95                   <xsl:when test="fn:contains(@name,'.xpgt')"><xsl:value-of select="fn:concat($cssdir,'/',@name)"/></xsl:when>
 96                 </xsl:choose>
 97               </xsl:attribute>
 98               <xsl:attribute name="media-type">
 99                 <xsl:choose>
100                   <xsl:when test="fn:contains(@name,'.css')">text/css</xsl:when>
101                   <xsl:when test="fn:contains(@name,'.gif')">image/gif</xsl:when>
102                   <xsl:when test="fn:contains(@name,'.jpg')">image/jpeg</xsl:when>
103                   <xsl:when test="fn:contains(@name,'.svg')">image/svg+xml</xsl:when>
104                   <xsl:when test="fn:contains(@name,'.png')">image/png</xsl:when>
105                   <xsl:when test="fn:contains(@name,'.xpgt')">application/vnd.adobe-page-template+xml</xsl:when>
106                 </xsl:choose>
107               </xsl:attribute>
108             </item>
109           </xsl:for-each>
110 
111           <!-- Fonts -->
112           <xsl:for-each select="dateien/fonts/font">
113             <item id="epub.embedded.font{fn:position()}" href="{$fontdir}/{@name}">
114               <xsl:attribute name="media-type">
115                 <xsl:choose>
116                   <xsl:when test="fn:contains(@name,'.otf')">application/vnd.ms-opentype</xsl:when><!-- alt: font/opentype -->
117                   <xsl:when test="fn:contains(@name,'.ttf')">application/x-font-ttf</xsl:when><!-- alt: font/truetype -->
118                 </xsl:choose>
119               </xsl:attribute>
120             </item>
121           </xsl:for-each>
122 
123           <!-- Bilder aus dem Inhaltsbereich -->
124           <xsl:for-each select="inhalt//bild">
125             <item id="bild{fn:position()}" href="{$imgdir}/{@name}">
126               <xsl:attribute name="media-type">
127                 <xsl:choose>
128                   <xsl:when test="fn:contains(@name,'.gif')">image/gif</xsl:when>
129                   <xsl:when test="fn:contains(@name,'.jpg')">image/jpeg</xsl:when>
130                   <xsl:when test="fn:contains(@name,'.png')">image/png</xsl:when>
131                   <xsl:when test="fn:contains(@name,'.svg')">image/svg+xml</xsl:when>
132                 </xsl:choose>
133               </xsl:attribute>
134             </item>
135           </xsl:for-each>
136 
137           <!-- Titelseite -->
138           <item id="{$coverid}" media-type="application/xhtml+xml" href="{$htmldir}/{fn:lower-case($coverid)}.html"/>
139 
140           <!-- Inhaltsverzeichnis -->
141           <item id="{$tocid}" media-type="application/xhtml+xml" href="{$htmldir}/{$tocpage}"/>
142 
143           <!-- XHTML-Kapitel -->
144           <xsl:for-each select="inhalt/kapitel">
145             <item id="kap{fn:position()}" media-type="application/xhtml+xml" href="{$htmldir}/kapitel{fn:position()}.html"/>
146           </xsl:for-each>
147         </manifest>
148 
149         <spine toc="toc">
150           <itemref idref="{$coverid}" linear="no"/>
151           <itemref idref="{$tocid}"/>
152           <xsl:for-each select="inhalt/kapitel">
153             <itemref idref="kap{fn:position()}"/>
154           </xsl:for-each>
155         </spine>
156 
157         <guide>
158           <reference type="cover" title="{$coverid}" href="{$htmldir}/{fn:lower-case($coverid)}.html"/>
159           <reference type="toc" title="{$tocid}" href="{$htmldir}/{$tocpage}"/>
160           <xsl:for-each select="inhalt/kapitel">
161             <reference type="text" title="{@titel}" href="{$htmldir}/kapitel{fn:position()}.html"/>
162           </xsl:for-each>
163         </guide>
164 
165       </package>
166     </xsl:result-document>
167 
168 
169     <!-- toc.ncx im Verzeichnis OPS (beide Namen sind variabel) -->
170     <xsl:result-document href="{$epubdir}/{$opsdir}/{$tocfile}" format="tocncx">
171       <ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" xml:lang="{if(metadaten/sprache) then metadaten/sprache else 'en'}" version="2005-1">
172 
173         <!-- Navigationstiefe als maximale Verschachtelung der abschnitt-Elemente mit Wert ≥ 1 -->
174         <xsl:variable name="nav_depth" select="fn:max(for $a in //abschnitt return fn:count($a/ancestor-or-self::abschnitt))"/>
175 
176         <head>
177           <meta name="dtb:uid" content="{metadaten/ident}"/>
178           <meta name="dtb:depth" content="{if($nav_depth ge 1) then $nav_depth else 1}"/>
179           <meta name="dtb:totalPageCount" content="0"/>
180           <meta name="dtb:maxPageNumber" content="0"/>
181         </head>
182 
183         <docTitle>
184           <text><xsl:value-of select="metadaten/titel"/></text>
185         </docTitle>
186 
187         <navMap>
188           <navPoint id="navPoint-1" playOrder="1">
189             <navLabel>
190               <text>Titel</text>
191             </navLabel>
192             <content src="{$htmldir}/{fn:lower-case($coverid)}.html"/>
193           </navPoint>
194 
195           <navPoint id="navPoint-2" playOrder="2">
196             <navLabel>
197               <text>Inhalt</text>
198             </navLabel>
199             <content src="{$htmldir}/{$tocpage}"/>
200           </navPoint>
201 
202           <xsl:for-each select="inhalt/kapitel">
203             <xsl:apply-templates select="abschnitt" mode="toc">
204               <xsl:with-param name="k_pos" select="fn:position()"/>
205               <xsl:with-param name="a_anz" select="fn:count(descendant::abschnitt)"/>
206             </xsl:apply-templates>
207           </xsl:for-each>
208 
209         </navMap>
210 
211       </ncx>
212     </xsl:result-document>
213 
214 
215     <!-- HTML-Deckblatt mit Coverbild -->
216     <xsl:result-document href="{$epubdir}/{$opsdir}/{$htmldir}/{fn:lower-case($coverid)}.html" format="xhtml11">
217       <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="{if(metadaten/sprache) then metadaten/sprache else 'en'}">
218 
219         <head>
220           <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
221           <meta name="description" content="EPUB - {$coverid}" />
222           <xsl:if test="fn:string-length($css) > 0">
223             <link rel="stylesheet" type="text/css" href="../{$cssdir}/{$css}" />
224           </xsl:if>
225           <xsl:if test="fn:string-length($ade) > 0">
226             <link rel="stylesheet" type="application/vnd.adobe-page-template+xml" href="../{$cssdir}/{$ade}" />
227           </xsl:if>
228           <title><xsl:value-of select="metadaten/titel"/></title>
229         </head>
230 
231         <body>
232           <p id="cover">
233             <img src="../{$imgdir}/{dateien/datei[@id='coverimage']/@name}" height="90%" alt="{$coverid}" title="" />
234           </p>
235         </body>
236 
237       </html>
238     </xsl:result-document>
239 
240 
241     <!-- Inhaltsverzeichnis -->
242     <xsl:result-document href="{$epubdir}/{$opsdir}/{$htmldir}/{$tocpage}" format="xhtml11">
243       <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="{if(metadaten/sprache) then metadaten/sprache else 'en'}">
244 
245         <head>
246           <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
247           <meta name="description" content="EPUB - Inhalt" />
248           <xsl:if test="fn:string-length($css) > 0">
249             <link rel="stylesheet" type="text/css" href="../{$cssdir}/{$css}" />
250           </xsl:if>
251           <xsl:if test="fn:string-length($ade) > 0">
252             <link rel="stylesheet" type="application/vnd.adobe-page-template+xml" href="../{$cssdir}/{$ade}" />
253           </xsl:if>
254           <title>Inhaltsverzeichnis</title>
255         </head>
256 
257         <body>
258           <h1>Inhaltsverzeichnis</h1>
259             <ul id="inhalt">
260               <xsl:for-each select="inhalt/kapitel">
261                 <li><a href="kapitel{fn:position()}.html"><xsl:value-of select="fn:concat('Kapitel ',fn:position(),': ',@titel)"/></a></li>
262               </xsl:for-each>
263             </ul>
264         </body>
265 
266       </html>
267     </xsl:result-document>
268 
269 
270     <!-- Kapitelverarbeitung ... -->
271     <xsl:apply-templates select="inhalt/kapitel"/>
272   </xsl:template>
273 
274 
275   <!-- Unterabschnitte in TOC verarbeiten -->
276   <xsl:template match="abschnitt" mode="toc">
277     <xsl:param name="k_pos"/>
278     <xsl:param name="a_anz"/>
279 
280     <xsl:variable name="a_pos" select="fn:position()"/>
281     <xsl:variable name="a_id" select="generate-id()"/>
282     <xsl:variable name="p_ord" select="fn:count(ancestor-or-self::abschnitt) + fn:count(preceding::abschnitt) + 2"/>
283 
284     <navPoint id="navPoint-{$p_ord}" playOrder="{$p_ord}" xmlns="http://www.daisy.org/z3986/2005/ncx/">
285 
286       <navLabel>
287         <text><xsl:value-of select="@titel"/></text>
288       </navLabel>
289 
290       <xsl:choose>
291         <xsl:when test="$a_pos = 1 and $a_anz = 1">
292           <content src="{$htmldir}/kapitel{$k_pos}.html"/>
293         </xsl:when>
294         <xsl:otherwise>
295           <content src="{$htmldir}/kapitel{$k_pos}.html#{$a_id}"/>
296         </xsl:otherwise>
297       </xsl:choose>
298 
299       <xsl:if test="$a_anz > 1">
300         <xsl:apply-templates select="abschnitt" mode="toc">
301           <xsl:with-param name="k_pos" select="$k_pos"/>
302           <xsl:with-param name="a_anz" select="$a_anz"/>
303         </xsl:apply-templates>
304       </xsl:if>
305     </navPoint>
306   </xsl:template>
307 
308 
309   <!-- Kapitelinhalte als XHTML-Dateien ausgeben -->
310   <xsl:template match="kapitel">
311     <xsl:result-document href="{$epubdir}/{$opsdir}/{$htmldir}/kapitel{fn:position()}.html" format="xhtml11">
312       <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="{if(/buch/metadaten/sprache) then /buch/metadaten/sprache else 'en'}">
313 
314         <head>
315           <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
316           <meta name="description" content="EPUB - Kapitel {fn:position()}" />
317           <xsl:if test="fn:string-length($css) > 0">
318             <link rel="stylesheet" type="text/css" href="../{$cssdir}/{$css}" />
319           </xsl:if>
320           <xsl:if test="fn:string-length($ade) > 0">
321             <link rel="stylesheet" type="application/vnd.adobe-page-template+xml" href="../{$cssdir}/{$ade}" />
322           </xsl:if>
323           <title><xsl:value-of select="@titel"/></title>
324         </head>
325 
326         <body>
327           <h1><xsl:value-of select="@titel"/></h1>
328           <xsl:apply-templates select="abschnitt" mode="html"/>
329         </body>
330 
331       </html>
332     </xsl:result-document>
333   </xsl:template>
334 
335 
336   <!-- Verarbeitung der Inhalte zu XHTML -->
337   <xsl:template match="abschnitt" mode="html">
338     <xsl:variable name="a_id" select="generate-id()"/>
339     <xsl:variable name="h_x" select="fn:count(ancestor::abschnitt) + 2"/>
340 
341     <xsl:element name="h{if($h_x le 6) then $h_x else 6}">
342       <xsl:attribute name="id">
343         <xsl:value-of select="$a_id"/>
344       </xsl:attribute>
345       <xsl:value-of select="@titel"/>
346     </xsl:element>
347     <xsl:apply-templates mode="html"/>
348   </xsl:template>
349 
350 
351   <!-- XHTML-Absätze -->
352   <xsl:template match="absatz" mode="html">
353     <xsl:choose>
354       <xsl:when test="fn:count(preceding-sibling::absatz) = 0 and parent::abschnitt/parent::kapitel">
355         <p class="first">
356           <xsl:apply-templates mode="html"/>
357         </p>
358       </xsl:when>
359       <xsl:otherwise>
360         <p>
361           <xsl:apply-templates mode="html"/>
362         </p>
363       </xsl:otherwise>
364     </xsl:choose>
365   </xsl:template>
366 
367 
368   <!-- XHTML-Bilder (Raster- bzw. Vektorgrafiken) -->
369   <xsl:template match="bild" mode="html">
370      <div class="abb">
371        <img src="../{$imgdir}/{@name}" alt="{@beschreibung}">
372          <xsl:if test="fn:string-length(@breite) > 0">
373            <xsl:attribute name="width">
374              <xsl:value-of select="@breite"/>
375            </xsl:attribute>
376          </xsl:if>
377          <xsl:if test="fn:string-length(@hoehe) > 0">
378            <xsl:attribute name="height">
379              <xsl:value-of select="@hoehe"/>
380            </xsl:attribute>
381          </xsl:if>
382          <xsl:if test="fn:string-length(@titel) > 0">
383            <xsl:attribute name="title">
384              <xsl:value-of select="@titel"/>
385            </xsl:attribute>
386          </xsl:if>
387        </img>
388        <p><xsl:value-of select="fn:concat('Abb. ',fn:count(preceding::bild) + 1,': ',@titel)"/></p>
389      </div>
390   </xsl:template>
391 
392 
393   <!-- XHTML-Verweise -->
394   <xsl:template match="verweis" mode="html">
395     <a href="{@ziel}"><xsl:value-of select="."/></a>
396   </xsl:template>
397 
398 
399   <!-- XHTML-Texthervorhebung (normal hervorgehoben) -->
400   <xsl:template match="text[@ttyp='normal']" mode="html">
401     <em><xsl:value-of select="."/></em>
402   </xsl:template>
403 
404 
405   <!-- XHTML-Texthervorhebung (stark hervorgehoben) -->
406   <xsl:template match="text[@ttyp='stark']" mode="html">
407     <strong><xsl:value-of select="."/></strong>
408   </xsl:template>
409 
410 
411   <!-- XHTML-Listen -->
412   <xsl:template match="liste[@ltyp='u']" mode="html">
413     <ul>
414       <xsl:for-each select="eintrag">
415         <li><xsl:value-of select="."/></li>
416       </xsl:for-each>
417     </ul>
418   </xsl:template>
419 
420 
421   <xsl:template match="liste[@ltyp='g']" mode="html">
422     <ol>
423       <xsl:for-each select="eintrag">
424         <li><xsl:value-of select="."/></li>
425       </xsl:for-each>
426     </ol>
427   </xsl:template>
428 
429 
430   <!-- XHTML-Quelltext | Zeilennummer: Zeileninhalt -->
431   <xsl:template match="quelltext" mode="html">
432     <xsl:variable name="zeilen" select="fn:tokenize(.,'\n')"/>
433     <xsl:variable name="z_max" select="fn:string-length(fn:string(fn:count($zeilen)))"/>
434     <pre>
435       <xsl:for-each select="$zeilen">
436         <xsl:variable name="z_nr" select="fn:position()"/>
437         <xsl:variable name="z_akt" select="fn:string-length(fn:string($z_nr))"/>
438         <xsl:variable name="leer" select="fn:string-join((for $i in 1 to $z_max - $z_akt return ' '),'')"/>
439         <xsl:value-of select="fn:concat($leer,$z_nr,': ',fn:normalize-space(.),'&#xA;')"/>
440       </xsl:for-each>
441     </pre>
442   </xsl:template>
443 
444 
445   <!-- XHTML-Tabellen -->
446   <xsl:template match="tabelle" mode="html">
447     <table summary="{@titel}">
448       <thead>
449         <tr>
450           <xsl:for-each select="kopfreihe/zelle">
451             <th><xsl:value-of select="."/></th>
452           </xsl:for-each>
453         </tr>
454       </thead>
455       <tbody>
456         <xsl:for-each select="datenreihe">
457           <tr>
458             <xsl:for-each select="zelle">
459               <td><xsl:value-of select="."/></td>
460             </xsl:for-each>
461           </tr>
462         </xsl:for-each>
463       </tbody>
464     </table>
465   </xsl:template>
466 
467 </xsl:stylesheet>

Code formatiert mit »Highlight 3.5«