<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:css="http://www.daisy.org/ns/pipeline/braille-css" xmlns:s="org.daisy.pipeline.braille.css.xpath.Style" xmlns:t="org.daisy.pipeline.braille.css.xpath.StyledText" xmlns:pf="http://www.daisy.org/ns/pipeline/functions" version="3.0" exclude-result-prefixes="#all"> <xsl:import href="http://www.daisy.org/pipeline/modules/braille/css-utils/library.xsl"/> <xsl:include href="http://www.daisy.org/pipeline/modules/common-utils/library.xsl"/> <xsl:param name="braille-charset"/> <xsl:param name="translate-attributes" select="''" static="yes"> </xsl:param> <xsl:param name="include-braille-code-in-language" as="xs:boolean" select="false()"/> <xsl:template match="css:block"> <xsl:message terminate="yes">Coding error</xsl:message> </xsl:template> <xsl:template match="/*"> <xsl:apply-templates select="." mode="identify-blocks"/> </xsl:template> <xsl:variable name="TEXT_TRANSFORM_NONE" as="item()" select="css:parse-stylesheet('text-transform: none')"/> <xsl:variable name="BRAILLE_CHARSET_VALUE" as="xs:string" select="if ($braille-charset!='') then 'custom' else 'unicode'"/> <xsl:variable name="BRAILLE_CHARSET_DECLARATION" as="item()" select="css:parse-stylesheet(concat('braille-charset: ',$BRAILLE_CHARSET_VALUE))"/> <xsl:template mode="identify-blocks" match="/*"> <xsl:next-match> <xsl:with-param name="source-style" tunnel="yes" select="()"/> <xsl:with-param name="source-language" tunnel="yes" select="()"/> <xsl:with-param name="result-style" tunnel="yes" select="()"/> <xsl:with-param name="result-language" tunnel="yes" select="()"/> <xsl:with-param name="portion" select="1.0"/> </xsl:next-match> </xsl:template> <xsl:variable name="text-properties" as="xs:string*" select="('white-space', 'hyphens', 'hyphenate-character', 'text-transform', 'braille-charset', 'letter-spacing', 'word-spacing')"/> <xsl:template mode="identify-blocks" match="*"> <xsl:param name="is-block" as="xs:boolean" select="true()" tunnel="yes"/> <xsl:param name="source-style" as="item()?" tunnel="yes"/> <xsl:param name="source-language" as="xs:string?" tunnel="yes"/> <xsl:param name="result-style" as="item()?" tunnel="yes"/> <xsl:param name="result-language" as="xs:string?" tunnel="yes"/> <xsl:param name="portion" required="yes"/> <xsl:variable name="source-style" as="item()?" select="css:parse-stylesheet(@style,$source-style)"/> <xsl:variable name="source-style" as="item()?" select="s:merge(($source-style,@css:*/css:parse-stylesheet(.)))"/> <xsl:variable name="source-language" as="xs:string?" select="(@xml:lang/string(.),$source-language)[1]"/> <xsl:variable name="translated-style" as="item()?"> <xsl:choose> <xsl:when test="exists(s:get($source-style,'content'))"> <xsl:sequence select="$source-style"/>"/> </xsl:when> <xsl:otherwise> <xsl:call-template name="translate-style"> <xsl:with-param name="style" select="$source-style"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="translated-language" as="xs:string?"> <xsl:call-template name="translated-language"> <xsl:with-param name="source-style" tunnel="yes" select="$source-style"/> <xsl:with-param name="source-language" tunnel="yes" select="$source-language"/> <xsl:with-param name="translated-style" select="$translated-style"/> </xsl:call-template> </xsl:variable> <xsl:variable name="style" as="attribute()?" select="css:style-attribute(css:serialize-stylesheet($translated-style,$result-style))"/> <xsl:variable name="lang" as="attribute()?"> <xsl:for-each select="$translated-language[not(.=$result-language)]"> <xsl:attribute name="xml:lang" select="."/> </xsl:for-each> </xsl:variable> <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}"> <xsl:sequence select="$style"/> <xsl:sequence select="$lang"/> <xsl:apply-templates mode="#current" select="@* except (@style|@css:*|@xml:lang)"> <xsl:with-param name="source-style" tunnel="yes" select="$source-style"/> <xsl:with-param name="source-language" tunnel="yes" select="$source-language"/> </xsl:apply-templates> <xsl:variable name="is-block" as="xs:boolean" select="$is-block and descendant-or-self::*[@css:display[not(.='inline')]]"/> <xsl:for-each-group select="*|text()" group-adjacent="$is-block and boolean(descendant-or-self::*[@css:display[not(.='inline')]])"> <xsl:variable name="group-portion" select="$portion div last()"/> <xsl:choose> <xsl:when test="current-grouping-key()"> <xsl:for-each select="current-group()"> <xsl:variable name="group-portion" select="$group-portion div last()"/> <xsl:apply-templates mode="#current" select="."> <xsl:with-param name="is-block" select="$is-block" tunnel="yes"/> <xsl:with-param name="source-style" tunnel="yes" select="$source-style"/> <xsl:with-param name="source-language" tunnel="yes" select="$source-language"/> <xsl:with-param name="result-style" tunnel="yes" select="$translated-style"/> <xsl:with-param name="result-language" tunnel="yes" select="$translated-language"/> <xsl:with-param name="portion" select="$group-portion"/> </xsl:apply-templates> </xsl:for-each> </xsl:when> <xsl:when test="every $n in current-group() satisfies $n/self::text() and matches(string($n),'^[ \t\n\r⠀­​]*$')"> <xsl:call-template name="pf:progress"> <xsl:with-param name="progress" select="string($group-portion)"/> </xsl:call-template> <xsl:value-of select="."/> </xsl:when> <xsl:otherwise> <xsl:variable name="block"> <xsl:element name="css:block"> <xsl:for-each select="current-group()"> <xsl:sequence select="."/> </xsl:for-each> </xsl:element> </xsl:variable> <xsl:call-template name="pf:progress"> <xsl:with-param name="progress" select="string($group-portion)"/> </xsl:call-template> <xsl:apply-templates select="$block/css:block"> <xsl:with-param name="source-style" tunnel="yes" select="$source-style"/> <xsl:with-param name="source-language" tunnel="yes" select="$source-language"/> <xsl:with-param name="result-style" tunnel="yes" select="$translated-style"/> <xsl:with-param name="result-language" tunnel="yes" select="$translated-language"/> <xsl:with-param name="portion" select="$group-portion"/> </xsl:apply-templates> </xsl:otherwise> </xsl:choose> </xsl:for-each-group> </xsl:element> </xsl:template> <xsl:template mode="identify-blocks" match="text()|@*"> <xsl:sequence select="."/> </xsl:template> <xsl:template name="translate-style" as="item()?"> <xsl:param name="style" as="item()?" required="yes"/> <xsl:variable name="style" as="item()*"> <xsl:for-each select="s:iterate($style)"> <xsl:choose> <xsl:when test="exists(s:property(.))"> <xsl:variable name="property" as="xs:string" select="s:property(.)"/> <xsl:variable name="value" as="xs:string" select="string(s:get($style,$property))"/> <xsl:choose> <xsl:when test="$property='text-transform' and not($value='none')"> </xsl:when> <xsl:when test="$property='braille-charset' and not($value=$BRAILLE_CHARSET_VALUE)"> </xsl:when> <xsl:when test="$property='hyphens' and $value='auto'"> </xsl:when> <xsl:otherwise> <xsl:sequence select="."/> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:when test="exists(s:selector(.))"> <xsl:sequence select="."/> </xsl:when> <xsl:otherwise> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:variable> <xsl:sequence select="s:merge(($TEXT_TRANSFORM_NONE,$BRAILLE_CHARSET_DECLARATION,$style))"/> </xsl:template> <xsl:template mode="text-items" match="*" as="item()*"> <xsl:param name="source-style" as="item()?" tunnel="yes"/> <xsl:param name="source-language" as="xs:string?" tunnel="yes"/> <xsl:variable name="source-style" as="item()?" select="css:parse-stylesheet(@style,$source-style)"/> <xsl:variable name="source-language" as="xs:string?" select="(@xml:lang/string(.),$source-language)[1]"/> <xsl:apply-templates mode="#current"> <xsl:with-param name="source-style" tunnel="yes" select="$source-style"/> <xsl:with-param name="source-language" tunnel="yes" select="$source-language"/> </xsl:apply-templates> </xsl:template> <xsl:template mode="text-items" match="text()" as="item()"> <xsl:param name="source-style" as="item()?" tunnel="yes"/> <xsl:param name="source-language" as="xs:string?" tunnel="yes"/> <xsl:variable name="source-style" as="item()?" select="css:parse-stylesheet((),$source-style)"/> <xsl:sequence select="t:of(string(.),$source-style,$source-language)"/> </xsl:template> <xsl:template mode="treewalk" match="*"> <xsl:param name="new-text-nodes" as="item()*" required="yes"/> <xsl:param name="source-style" as="item()?" tunnel="yes"/> <xsl:param name="source-language" as="xs:string?" tunnel="yes"/> <xsl:param name="result-style" as="item()?" tunnel="yes"/> <xsl:param name="result-language" as="xs:string?" tunnel="yes"/> <xsl:variable name="text-node-count" select="count(.//text())"/> <xsl:variable name="source-style" as="item()?" select="css:parse-stylesheet(@style,$source-style)"/> <xsl:variable name="source-style" as="item()?" select="s:merge(($source-style,@css:*/css:parse-stylesheet(.)))"/> <xsl:variable name="source-language" as="xs:string?" select="(@xml:lang/string(.),$source-language)[1]"/> <xsl:variable name="translated-style" as="item()?"> <xsl:choose> <xsl:when test="exists(s:get($source-style,'content'))"> <xsl:sequence select="$source-style"/> </xsl:when> <xsl:otherwise> <xsl:call-template name="translate-style"> <xsl:with-param name="style" select="$source-style"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="translated-language" as="xs:string?"> <xsl:call-template name="translated-language"> <xsl:with-param name="source-style" tunnel="yes" select="$source-style"/> <xsl:with-param name="source-language" tunnel="yes" select="$source-language"/> <xsl:with-param name="translated-style" select="$translated-style"/> </xsl:call-template> </xsl:variable> <xsl:variable name="style" as="attribute()?" select="css:style-attribute(css:serialize-stylesheet($translated-style,$result-style))"/> <xsl:variable name="lang" as="attribute()?"> <xsl:for-each select="$translated-language[not(.=$result-language)]"> <xsl:attribute name="xml:lang" select="."/> </xsl:for-each> </xsl:variable> <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}"> <xsl:sequence select="$style"/> <xsl:sequence select="$lang"/> <xsl:apply-templates mode="#current" select="@* except (@style|@css:*|@xml:lang)"> <xsl:with-param name="source-style" tunnel="yes" select="$source-style"/> <xsl:with-param name="source-language" tunnel="yes" select="$source-language"/> </xsl:apply-templates> <xsl:if test="empty(s:get($translated-style,'content'))"> <xsl:apply-templates mode="#current" select="child::node()[1]"> <xsl:with-param name="new-text-nodes" select="$new-text-nodes[position()<=$text-node-count]"/> <xsl:with-param name="source-style" tunnel="yes" select="$source-style"/> <xsl:with-param name="source-language" tunnel="yes" select="$source-language"/> <xsl:with-param name="result-style" tunnel="yes" select="$translated-style"/> <xsl:with-param name="result-language" tunnel="yes" select="$translated-language"/> </xsl:apply-templates> </xsl:if> </xsl:element> <xsl:apply-templates mode="#current" select="following-sibling::node()[1]"> <xsl:with-param name="new-text-nodes" select="$new-text-nodes[position()>$text-node-count]"/> </xsl:apply-templates> </xsl:template> <xsl:template mode="treewalk" match="text()"> <xsl:param name="new-text-nodes" as="item()*" required="yes"/> <xsl:param name="result-style" as="item()*" tunnel="yes"/> <xsl:param name="result-language" as="xs:string?" tunnel="yes"/> <xsl:variable name="text" as="xs:string" select="t:getText($new-text-nodes[1])"/> <xsl:variable name="translated-style" as="item()?" select="t:getStyle($new-text-nodes[1])"/> <xsl:variable name="translated-language" as="xs:string?" select="t:getLanguage($new-text-nodes[1])"/> <xsl:variable name="style" as="attribute()?" select="css:style-attribute(css:serialize-stylesheet($translated-style,$result-style))"/> <xsl:variable name="lang" as="attribute()?"> <xsl:for-each select="$translated-language[not(.=$result-language)]"> <xsl:attribute name="xml:lang" select="."/> </xsl:for-each> </xsl:variable> <xsl:choose> <xsl:when test="empty($style) and empty($lang) or $text='' or normalize-space($text)='' and not(s:get($translated-style,'white-space')[not(string(.)='normal')])"> <xsl:value-of select="$text"/> </xsl:when> <xsl:otherwise> <_> <xsl:sequence select="$style"/> <xsl:sequence select="$lang"/> <xsl:value-of select="$text"/> </_> </xsl:otherwise> </xsl:choose> <xsl:apply-templates mode="#current" select="following-sibling::node()[1]"> <xsl:with-param name="new-text-nodes" select="$new-text-nodes[position()>1]"/> </xsl:apply-templates> </xsl:template> <xsl:template mode="treewalk" match="@*"> <xsl:sequence select="."/> </xsl:template> <xsl:template mode="identify-blocks treewalk" _match="{$translate-attributes}" use-when="$translate-attributes!=''"> <xsl:param name="source-style" as="item()?" tunnel="yes"/> <xsl:param name="source-language" as="xs:string?" tunnel="yes"/> <xsl:choose> <xsl:when test="self::attribute()"> <xsl:variable name="block"> <xsl:element name="css:block"> <xsl:value-of select="string(.)"/> </xsl:element> </xsl:variable> <xsl:variable name="translated-block"> <xsl:apply-templates select="$block/css:block"/> </xsl:variable> <xsl:attribute name="{name()}" select="string($translated-block)"/> </xsl:when> <xsl:otherwise> <xsl:next-match/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="translated-language" as="xs:string?"> <xsl:param name="source-language" as="xs:string?" tunnel="yes"/> <xsl:param name="result-language" as="xs:string?" tunnel="yes"/> <xsl:param name="translated-style" as="item()?"/> <xsl:choose> <xsl:when test="$include-braille-code-in-language"> <xsl:variable name="block"> <xsl:element name="css:block"> <xsl:text>xxx</xsl:text> </xsl:element> </xsl:variable> <xsl:variable name="translated-block" as="node()*"> <xsl:apply-templates select="$block/css:block"/> </xsl:variable> <xsl:sequence select="($translated-block/self::*[1]/@xml:lang/string(.), $result-language)[1]"/> </xsl:when> <xsl:when test="empty($source-language)"/> <xsl:when test="s:get($translated-style,'text-transform')[string(.)='none']"> <xsl:sequence select="replace($source-language, '^([a-zA-Z]{2,8})(?:-[A-Z][a-z]{3})?(-.+)?$', '$1-Brai$2')"/> </xsl:when> <xsl:otherwise> <xsl:sequence select="$source-language"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>