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(.),'
')"/> 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«