<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.daisy.org/z3986/2005/dtbook/" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:pfunc="http://www.daisy.org/pipeline/xslt/function" version="2.0" exclude-result-prefixes="xs html pfunc"> <xsl:output method="xml" encoding="UTF-8" indent="yes" doctype-public="-//NISO//DTD dtbook 2005-2//EN" doctype-system="http://www.daisy.org/z3986/2005/dtbook-2005-2.dtd"/> <xsl:param name="uid" as="xs:string" select="'[UID]'"/> <xsl:param name="title" as="xs:string" select="'[DTB_TITLE]'"/> <xsl:param name="cssURI" as="xs:string" select="'[cssURI]'"/> <xsl:param name="nccURI" as="xs:string" select="'[nccURI]'"/> <xsl:param name="transferDcMetadata" as="xs:string" select="'false'"/> <xsl:param name="transformationMode" as="xs:string" select="'standalone'"/> <xsl:variable name="nccURI.mod" as="xs:string" select="translate($nccURI,'\','/')"/> <xsl:variable name="cssURI.mod" as="xs:string" select="replace(translate($cssURI,'\','/'),'.*/(.+)','$1')"/> <xsl:variable name="dtbMigration" as="xs:boolean" select="matches($transformationMode,'DTBmigration','i')"/> <xsl:variable name="regexpMatchTitle" as="xs:string" select="'^title$|^dc:title$|^dtb:title$'"/> <xsl:variable name="regexpMatchID" as="xs:string" select="'^id$|^dc:id$|^dtb:id$|^uid$|^dc:uid$|^dtb:uid$|^identifier$|^dc:identifier$|^dtb:identifier$'"/> <xsl:variable name="regexpMatchTitleAndID" as="xs:string" select="concat($regexpMatchTitle,'|',$regexpMatchID)"/> <xsl:variable name="smil" as="xs:string" select="'.smil#'"/> <xsl:variable name="xTitle" as="xs:string"> <xsl:choose> <xsl:when test="$title eq '' or $title eq '[DTB_TITLE]'"> <xsl:choose> <xsl:when test="html:html/html:head/html:title"> <xsl:value-of select="html:html/html:head/html:title"/> </xsl:when> <xsl:when test="//html:meta[matches(@name,$regexpMatchTitle,'i')]"> <xsl:value-of select="//html:meta[matches(@name,$regexpMatchTitle,'i')][1]/@content"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="''"/> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:value-of select="$title"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="xUID" as="xs:string"> <xsl:choose> <xsl:when test="$uid eq '' or $uid eq '[UID]'"> <xsl:choose> <xsl:when test="//html:meta[matches(@name,$regexpMatchID,'i')]"> <xsl:value-of select="//html:meta[matches(@name,$regexpMatchID,'i')][1]/@content"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="''"/> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:value-of select="$uid"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:template match="/"> <xsl:if test="$cssURI ne '[cssURI]' and $cssURI.mod ne ''"> <xsl:processing-instruction name="xml-stylesheet"> <xsl:text> type="text/css" href="</xsl:text> <xsl:value-of select="$cssURI.mod"/> <xsl:text>"</xsl:text> </xsl:processing-instruction> </xsl:if> <dtbook version="2005-2"> <xsl:copy-of select="html:html/@xml:lang"/> <xsl:apply-templates/> </dtbook> </xsl:template> <xsl:template match="html:head"> <head> <meta name="dtb:uid" content="{$xUID}"/> <meta name="dc:Title" content="{$xTitle}"/> <xsl:choose> <xsl:when test=" $dtbMigration and matches($transferDcMetadata,'true','i') and doc-available($nccURI.mod) and $nccURI ne '[nccURI]'"> <xsl:apply-templates select=" doc($nccURI.mod)//html:head/html:meta[ starts-with(@name,'dc:') and not( matches( @name, concat( $regexpMatchTitleAndID, '|^dc:format$' ), 'i' ) ) ]" mode="metadata-from-ncc"/> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="html:meta[not(matches(@name,$regexpMatchTitleAndID,'i'))]"/> </xsl:otherwise> </xsl:choose> </head> </xsl:template> <xsl:template match="html:meta[@http-equiv]" priority="10"/> <xsl:template match="html:meta[@name]"> <meta> <xsl:attribute name="name"> <xsl:choose> <xsl:when test="matches(@name,'^dc:(creator|subject|description|publisher|contributor|date|type|format|source|language|relation|coverage|rights)$','i')"> <xsl:value-of select="concat('dc:',pfunc:initialCaps(substring-after(@name,'dc:')))"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="@name"/> </xsl:otherwise> </xsl:choose> </xsl:attribute> <xsl:copy-of select="@content, @scheme"/> </meta> </xsl:template> <xsl:template match="html:meta[not(@name)]"> <meta> <xsl:copy-of select="@name, @content, @scheme"/> </meta> </xsl:template> <xsl:template match="html:meta" mode="metadata-from-ncc"> <xsl:if test="matches(@name,'^dc:(creator|subject|description|publisher|contributor|date|type|source|language|relation|coverage|rights)$','i')"> <meta> <xsl:attribute name="name" select="concat('dc:',pfunc:initialCaps(substring-after(@name,'dc:')))"/> <xsl:copy-of select="@content, @scheme, @http-equiv"/> </meta> </xsl:if> </xsl:template> <xsl:template match="html:link"> <link rel="stylesheet" type="text/css" href="{concat('dtbook_',@href)}"/> </xsl:template> <xsl:template match="html:body"> <book> <xsl:call-template name="copy-attributes"/> <xsl:if test="html:h1[@class eq 'frontmatter'] or //html:head/html:title"> <frontmatter> <xsl:apply-templates select="//html:head/html:title"/> <xsl:apply-templates select="html:h1[@class eq 'frontmatter']"/> </frontmatter> </xsl:if> <bodymatter> <xsl:apply-templates select="html:h1[not(@class eq 'frontmatter' or @class eq 'rearmatter')]"/> </bodymatter> <xsl:if test="html:h1[@class eq 'rearmatter']"> <rearmatter> <xsl:apply-templates select="html:h1[@class eq 'rearmatter']"/> </rearmatter> </xsl:if> </book> </xsl:template> <xsl:template match="html:title"> <doctitle> <xsl:apply-templates/> </doctitle> </xsl:template> <xsl:template match="element()[matches(local-name(),'^h[1-6]$')]"> <xsl:variable name="h.this.name" as="xs:string" select="local-name()"/> <xsl:variable name="h.this.level" as="xs:integer" select="xs:integer(substring-after($h.this.name,'h'))"/> <xsl:variable name="h.next" select="following-sibling::*[matches(local-name(),'^h[1-6]$')][1]"/> <xsl:variable name="h.next.name" select="local-name($h.next)"/> <xsl:variable name="e.up-to-next-heading" select=" if ($h.next) then following-sibling::*[. << $h.next] else following-sibling::*"/> <xsl:variable name="h.next-on-same-level-or-higher" select="following-sibling::*[matches(local-name(),concat('^h[1-',string($h.this.level),']$'))][1]"/> <xsl:variable name="h.next-level.all" select="following-sibling::*[matches(local-name(),concat('^h',string($h.this.level + 1),'$'))]"/> <xsl:variable name="h.next-level.relevant" select=" if ($h.next-on-same-level-or-higher) then $h.next-level.all[. << $h.next-on-same-level-or-higher] else $h.next-level.all"/> <xsl:variable name="NoRelevantElementsUntilNextHeading" as="xs:boolean" select="every $e in $e.up-to-next-heading satisfies matches(local-name($e),'^br$|^hr$')"/> <xsl:variable name="NextFollowingSiblingIsHeadingOnLowerLevel" as="xs:boolean" select="matches(local-name(following-sibling::*[not(matches(local-name(.),'^br$|^hr$'))][1]),concat('^h[',string($h.this.level+1),'-6]$'))"/> <xsl:element name="{concat('level',string($h.this.level))}"> <xsl:copy-of select="@class"/> <xsl:element name="{local-name()}"> <xsl:call-template name="copy-heading-attributes"/> <xsl:apply-templates/> </xsl:element> <xsl:apply-templates select="$e.up-to-next-heading"/> <xsl:if test="$NoRelevantElementsUntilNextHeading and not($NextFollowingSiblingIsHeadingOnLowerLevel)"> <p class="dummy"/> </xsl:if> <xsl:apply-templates select="$h.next-level.relevant"/> </xsl:element> </xsl:template> <xsl:template match="html:span[starts-with(@class,'page-')]"> <pagenum page="{substring-after(@class,'page-')}" id="{if (@id) then @id else concat('page-',normalize-space(.))}"> <xsl:call-template name="copy-page-attributes"/> <xsl:value-of select="normalize-space(.)"/> </pagenum> </xsl:template> <xsl:template match="html:span[@class eq 'sentence']"> <xsl:variable name="e.next" select="following-sibling::*[1]"/> <sent> <xsl:call-template name="copy-span-attributes"/> <xsl:apply-templates/> </sent> </xsl:template> <xsl:template match="html:span[ends-with(@class,'-prodnote')]"> <xsl:variable name="e.p.1" select="preceding-sibling::*[1]"/> <xsl:variable name="e.p.2" select="preceding-sibling::*[2]"/> <xsl:variable name="part-of-imggroup" as="xs:boolean" select=" local-name($e.p.1) eq 'img' or ( local-name($e.p.1) eq 'span' and $e.p.1/@class eq 'caption' and local-name($e.p.2) eq 'img' )"/> <xsl:choose> <xsl:when test="$part-of-imggroup"/> <xsl:otherwise> <prodnote render="{substring-before(@class,'-prodnote')}"> <xsl:call-template name="copy-span-attributes"/> <xsl:apply-templates/> </prodnote> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="html:span[ends-with(@class,'-prodnote')]" mode="inside-imgrp"> <xsl:param name="group-id" as="xs:string"/> <prodnote render="{substring-before(@class,'-prodnote')}" imgref="{concat('img-',$group-id)}" id="{concat('pnote-',$group-id)}"> <xsl:call-template name="copy-std-attr"/> <xsl:apply-templates/> </prodnote> </xsl:template> <xsl:template match="html:span[@class eq 'caption']"> <xsl:variable name="e.p.1" select="preceding-sibling::*[1]"/> <xsl:variable name="e.p.2" select="preceding-sibling::*[2]"/> <xsl:variable name="part-of-imggroup" as="xs:boolean" select=" local-name($e.p.1) eq 'img' or ( local-name($e.p.1) eq 'span' and ends-with($e.p.1/@class,'-prodnote') and local-name($e.p.2) eq 'img' )"/> <xsl:choose> <xsl:when test="$part-of-imggroup"/> <xsl:otherwise> <xsl:next-match/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="html:span[@class eq 'caption']" mode="inside-imgrp"> <xsl:param name="group-id" as="xs:string"/> <caption imgref="{concat('img-',$group-id)}" id="{concat('caption-',$group-id)}"> <xsl:call-template name="copy-std-attr"/> <xsl:apply-templates/> </caption> </xsl:template> <xsl:template match="html:body/html:span[@class eq 'noteref']" priority="5"> <p class="noteref"> <xsl:next-match/> </p> </xsl:template> <xsl:template match="html:span[@class eq 'noteref']" priority="3"> <noteref> <xsl:attribute name="idref" select="@bodyref (: if (contains(@bodyref,'#')) then substring-after(@bodyref,'#') else @bodyref :)"/> <xsl:copy-of select="@id"/> <xsl:call-template name="copy-std-attr"/> <xsl:apply-templates/> </noteref> </xsl:template> <xsl:template match="html:a[contains(@href,$smil)]"> <xsl:choose> <xsl:when test="$dtbMigration"> <xsl:apply-templates/> </xsl:when> <xsl:otherwise> <xsl:next-match/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="html:div[@class eq 'notebody']"> <note> <xsl:copy-of select="@id"/> <xsl:call-template name="copy-std-attr"/> <xsl:apply-templates/> </note> </xsl:template> <xsl:template match="html:img"> <xsl:variable name="e.f.1" select="following-sibling::*[1]"/> <xsl:variable name="e.f.2" select="following-sibling::*[2]"/> <xsl:variable name="imggrp.associate.first" as="xs:boolean" select=" local-name($e.f.1) eq 'span' and ends-with($e.f.1/@class,'-prodnote') or local-name($e.f.1) eq 'span' and $e.f.1/@class eq 'caption' "/> <xsl:variable name="imggrp.associate.second" as="xs:boolean" select=" ( local-name($e.f.1) eq 'span' and ends-with($e.f.1/@class,'-prodnote') and local-name($e.f.2) eq 'span' and $e.f.2/@class eq 'caption' ) or ( local-name($e.f.2) eq 'span' and ends-with($e.f.2/@class,'-prodnote') and local-name($e.f.1) eq 'span' and $e.f.1/@class eq 'caption' ) "/> <xsl:choose> <xsl:when test="$imggrp.associate.first"> <xsl:variable name="id" as="xs:string" select="generate-id()"/> <imggroup id="{concat('imggrp-',$id)}"> <img> <xsl:copy-of select="@src, @alt"/> <xsl:call-template name="copy-attributes-not-id"/> <xsl:attribute name="id" select="concat('img-',$id)"/> </img> <xsl:apply-templates select="$e.f.1" mode="inside-imgrp"> <xsl:with-param name="group-id" as="xs:string" select="$id"/> </xsl:apply-templates> <xsl:if test="$imggrp.associate.second"> <xsl:apply-templates select="$e.f.2" mode="inside-imgrp"> <xsl:with-param name="group-id" as="xs:string" select="$id"/> </xsl:apply-templates> </xsl:if> </imggroup> </xsl:when> <xsl:otherwise> <img> <xsl:copy-of select="@src, @alt"/> <xsl:call-template name="copy-attributes"/> </img> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="html:ol | html:ul"> <list type="{local-name()}"> <xsl:call-template name="copy-attributes"/> <xsl:apply-templates/> </list> </xsl:template> <xsl:template match="html:a | html:p | html:li | html:dl | html:dt | html:dd | html:span | html:strong | html:em | html:sub | html:sup | html:br | html:div | html:blockquote | html:abbr"> <xsl:element name="{local-name()}"> <xsl:call-template name="copy-attributes"/> <xsl:apply-templates/> </xsl:element> </xsl:template> <xsl:template match="html:div[html:span]"> <div> <xsl:call-template name="copy-attributes"/> <p class="inserted-by-transformer"> <xsl:apply-templates/> </p> </div> </xsl:template> <xsl:template match="html:body/html:br"> </xsl:template> <xsl:template match="html:table | html:table/html:caption | html:tr | html:td | html:th | html:col"> <xsl:element name="{local-name()}"> <xsl:call-template name="copy-table-attributes"/> <xsl:apply-templates/> </xsl:element> </xsl:template> <xsl:template name="copy-attributes"> <xsl:copy-of select="@id, @class, @href"/> <xsl:call-template name="copy-std-attr"/> </xsl:template> <xsl:template name="copy-attributes-not-id"> <xsl:copy-of select="@class, @href"/> <xsl:call-template name="copy-std-attr"/> </xsl:template> <xsl:template name="copy-heading-attributes"> <xsl:copy-of select="@id"/> <xsl:call-template name="copy-std-attr"/> </xsl:template> <xsl:template name="copy-table-attributes"> <xsl:copy-of select="@id, @rowspan, @colspan, @class, @valign"/> <xsl:call-template name="copy-std-attr"/> </xsl:template> <xsl:template name="copy-span-attributes"> <xsl:copy-of select="@id"/> <xsl:call-template name="copy-std-attr"/> </xsl:template> <xsl:template name="copy-page-attributes"> <xsl:call-template name="copy-std-attr"/> </xsl:template> <xsl:template name="copy-std-attr"> <xsl:copy-of select="@title, @dir, @xml:lang"/> <xsl:call-template name="smilref"/> </xsl:template> <xsl:template name="smilref"> <xsl:if test="$dtbMigration and contains(html:a[1]/@href,$smil)"> <xsl:attribute name="smilref" select="html:a[1]/@href"/> </xsl:if> </xsl:template> <xsl:template match="*"> <xsl:if test="local-name() ne 'html'"> <xsl:text> </xsl:text> <xsl:comment> **** No template for element: <xsl:value-of select="local-name()"/> **** </xsl:comment> </xsl:if> <xsl:apply-templates/> </xsl:template> <xsl:function name="pfunc:initialCaps" as="xs:string"> <xsl:param name="string" as="xs:string"/> <xsl:choose> <xsl:when test="boolean($string)"> <xsl:value-of select="string-join( ( upper-case(substring($string,1,1)), substring($string,2) ), '' ) "/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$string"/> </xsl:otherwise> </xsl:choose> </xsl:function> </xsl:stylesheet>