<?xml version="1.0" encoding="utf-8"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:rx="http://www.renderx.com/XSL/Extensions" xmlns:doc="www.pdfpower.com/docschema/documentation.xsd" version="1.0">
    
    <doc:styleinfo id="sxsl112rx">
        <title>XSL FO 1.1 to RenderX extensions conversion</title>
        <author>Lyudmila Novoselskaya</author>
        <dateCreated>2006-08-11</dateCreated>
        <filename>xsl11-to-rx-main.xsl</filename>
        <version major="1" minor="0" release="0" revision="$Revision: 1.11 $"/>
        <summary>
            XSL FO 1.1 to RenderX extensions stylesheets are intended to be used for conversion of XSL FO 1.1 elements and attributes to elements and attributes from RenderX extensions.
            Using these stylesheets you can convert XSL FO 1.1 documents to XSL FO 1.0 with RenderX extensions.
            The stylesheets support the following features:
            1. Document Outline (Bookmarks)(bookmarks-xsl11-to-rx.xsl).
            2. Indexes (indices-xsl11-to-rx.xsl).
            3. Last Page Number Reference (last-page-number-ref-xsl11-to-rx.xsl).
            4. Change Bars (change-bars-xsl11-to-rx.xsl).
            5. Folio prefix and suffix.
        </summary>
        <specifics>
            The following XSL FO 1.1 elements and attributes will be ignored since there is no correspondence in the RenderX extensions:
            - fo:page-sequence-wrapper
            - fo:flow-map
            - fo:flow-assignment
            - fo:flow-source-list
            - fo:flow-target-list
            - fo:flow-name-specifier
            - fo:region-name-specifier
            - fo:index-page-number-prefix
            - fo:index-page-number-suffix
            - @index-class
            - @merge-ranges-across-index-key-references
            - @merge-pages-across-index-key-references
            - Attributes for Conditional graphic scaling: @allowed-height-scale, @allowed-width-scale
        </specifics>
        <lastModified author="$Author: msulyaev $" time="$Modtime: 29.08.06 12:58 $"/>
    </doc:styleinfo>
    
    <xsl:output method="xml" version="1.0" indent="yes" encoding="utf-8"/>

    <xsl:key name="ids" match="fo:root/fo:page-sequence|fo:root/fo:page-sequence-wrapper//fo:page-sequence" use=".//*/@id"/>

    <!--bookmarks-xsl11-to-rx.xsl part
    -->
    <doc:pattern id="id-bookmark-tree" match="fo:bookmark-tree">
        <summary>Converts fo:bookmark-tree element to rx:outline</summary>
    </doc:pattern><xsl:template match="fo:bookmark-tree">
        <xsl:choose>
            <xsl:when test="fo:bookmark">
                <xsl:element name="rx:outline">
                    <xsl:apply-templates select="fo:bookmark"/>
                </xsl:element>
            </xsl:when>
            <xsl:otherwise>
                <xsl:message>At least one 'fo:bookmark' required as a child of 'fo:bookmark-tree'. 'fo:bookmark-tree' ignored.</xsl:message>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template><doc:pattern id="id-bookmark" match="fo:bookmark">
        <summary>Converts fo:bookmark element to rx:bookmark with keeping its attributes</summary>
    </doc:pattern><xsl:template match="fo:bookmark">
        <xsl:choose>
            <xsl:when test="fo:bookmark-title">
                <xsl:choose>
                    <xsl:when test="@external-destination | @internal-destination">
                        <xsl:element name="rx:bookmark">
                            <xsl:apply-templates select="  @external-destination
                                                         | @internal-destination
                                                         | @starting-state"/>
                            <xsl:apply-templates select="fo:bookmark-title"/>
                            <xsl:apply-templates select="fo:bookmark"/>
                        </xsl:element>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:message>Either '@external-destination' or '@internal-destination' is mandatory. 'fo:bookmark' ignored.</xsl:message>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:otherwise>
                <xsl:message>'fo:bookmark-title' is required as an initial child of 'fo:bookmark'. 'fo:bookmark' ignored.</xsl:message>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template><doc:pattern id="id-bookmark-title" match="fo:bookmark-title">
        <summary>Converts fo:bookmark-title element to rx:bookmark-label</summary>
    </doc:pattern><xsl:template match="fo:bookmark/fo:bookmark-title">
        <xsl:element name="rx:bookmark-label">
            <xsl:apply-templates select="text()"/>
        </xsl:element>
    </xsl:template><doc:pattern id="id-bookmark-external-destination" match="fo:bookmark/@external-destination">
        <summary>Converts fo:bookmark/@external-destination attribute to rx:bookmark/@external-destination</summary>
    </doc:pattern><xsl:template match="fo:bookmark/@external-destination">
        <xsl:attribute name="external-destination">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template><doc:pattern id="id-bookmark" match="fo:bookmark">
        <summary>Converts fo:bookmark element to rx:outline with keeping its attributes</summary>
    </doc:pattern><xsl:template match="fo:bookmark/@internal-destination">
        <xsl:attribute name="internal-destination">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
		<doc:pattern id="id-bookmark-starting-state" match="fo:bookmark/@starting-state">
        <summary>Converts fo:bookmark/@starting-state element to rx:bookmark/@collapse-subtree</summary>
    </doc:pattern><xsl:template match="fo:bookmark/@starting-state">
        <xsl:attribute name="collapse-subtree">
            <xsl:choose>
                <xsl:when test=". = 'hide'">true</xsl:when>
                <xsl:when test=". = 'show'">false</xsl:when>
                <xsl:otherwise>
                    <xsl:message>Invalid value '<xsl:value-of select="."/>' of '@starting-state'. Default value used.</xsl:message>
                    <xsl:text>false</xsl:text>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:attribute>
    </xsl:template>
    <!--indices-xsl11-to-rx.xsl part
    -->
    <doc:pattern id="id-index-range-begin" match="fo:index-range-begin">
        <summary>Converts fo:index-range-begin element to rx:begin-index-range</summary>
    </doc:pattern><xsl:template match="fo:index-range-begin">
        <xsl:element name="rx:begin-index-range">
            <xsl:choose>
                <xsl:when test="@id">
                    <xsl:apply-templates select="@id"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:message>Either '@id' is mandatory. 'fo:index-range-begin' ignored.</xsl:message>                    
                </xsl:otherwise>
            </xsl:choose>            
            <xsl:choose>
                <xsl:when test="@index-key">
                    <xsl:apply-templates select="@index-key"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:message>Either '@index-key' is mandatory. 'fo:index-range-begin' ignored.</xsl:message>                    
                </xsl:otherwise>
            </xsl:choose>            
        </xsl:element>
    </xsl:template><doc:pattern id="id-index-range-begin-id" match="fo:index-range-begin/@id">
        <summary>Converts fo:index-range-begin/@id attribute to rx:begin-index-range/@id</summary>
    </doc:pattern><xsl:template match="fo:index-range-begin/@id">
        <xsl:attribute name="id">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template><doc:pattern id="id-index-range-end" match="fo:index-range-end">
        <summary>Converts fo:index-range-end element to rx:end-index-range</summary>
    </doc:pattern><xsl:template match="fo:index-range-end">
        <xsl:element name="rx:end-index-range">
            <xsl:choose>
                <xsl:when test="@ref-id">
                    <xsl:apply-templates select="@ref-id"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:message>Either '@ref-id' is mandatory. 'fo:index-range-end' ignored.</xsl:message>                    
                </xsl:otherwise>
            </xsl:choose>            
        </xsl:element>
    </xsl:template><doc:pattern id="id-index-range-end-refid" match="fo:index-range-end">
        <summary>Converts fo:index-range-end/@ref-id attribute to rx:end-index-range/@ref-id</summary>
    </doc:pattern><xsl:template match="fo:index-range-end/@ref-id">
        <xsl:attribute name="ref-id">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template><doc:pattern id="id-index-key" match="@index-key">
        <summary>Converts @index-key attribute to @rx-key</summary>
    </doc:pattern><xsl:template match="@index-key">
        <xsl:attribute name="key" namespace="http://www.renderx.com/XSL/Extensions">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template><doc:pattern id="id-index-page-citation-list" match="fo:index-page-citation-list">
        <summary>Converts fo:index-page-citation-list element to rx:page-index</summary>
    </doc:pattern><xsl:template match="fo:index-page-citation-list">
        <xsl:choose>
            <xsl:when test="fo:index-key-reference">
                <xsl:element name="rx:page-index">
                    <xsl:if test="fo:index-key-reference/@merge-sequential-page-numbers | ancestor-or-self::*/@merge-sequential-page-numbers">
                        <xsl:apply-templates select="(fo:index-key-reference/@merge-sequential-page-numbers | ancestor-or-self::*/@merge-sequential-page-numbers)[position()=last()]" mode="inherit-merge-subsequent-page-numbers"/>
                    </xsl:if>
                    <xsl:if test="fo:index-page-citation-list-separator | ancestor-or-self::*/fo:index-page-citation-list-separator">
                        <xsl:apply-templates select="(fo:index-page-citation-list-separator | ancestor-or-self::*/fo:index-page-citation-list-separator)[position()=last()]" mode="inherit-list-separator"/>
                    </xsl:if>
                    <xsl:if test="fo:index-key-reference/fo:index-page-citation-range-separator | ancestor-or-self::*/fo:index-page-citation-range-separator">
                        <xsl:apply-templates select="(fo:index-key-reference/fo:index-page-citation-range-separator | ancestor-or-self::*/fo:index-page-citation-range-separator)[position()=last()]" mode="inherit-range-separator"/>
                    </xsl:if>
                    <xsl:apply-templates select="fo:index-key-reference"/>
                </xsl:element>
            </xsl:when>
            <xsl:otherwise>
                <xsl:message>At least one 'fo:index-key-reference' is required. Element 'fo:index-page-citation-list' ignored.</xsl:message>
                <xsl:choose>
                    <xsl:when test="@ref-index-key">
                        <xsl:apply-templates select="@ref-index-key"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:message>Invalid empty  element 'fo:index-page-citation-list' without @ref-index-key ignored.</xsl:message>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template><doc:pattern id="id-index-page-citation-range-separator" match="fo:index-page-citation-range-separator">
        <summary>fo:index-page-citation-range-separator element is only processed in inherit-range-separator mode</summary>
    </doc:pattern><xsl:template match="fo:index-page-citation-range-separator"/><doc:pattern id="id-index-page-citation-range-separator-inherit" match="fo:index-page-citation-range-separator">
        <summary>Converts fo:index-page-citation-range-separator element to @range-separator attribute</summary>
    </doc:pattern><xsl:template match="fo:index-page-citation-range-separator" mode="inherit-range-separator">
        <xsl:attribute name="range-separator">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template><doc:pattern id="id-index-page-citation-list-separator" match="fo:index-range-begin">
        <summary>fo:index-page-citation-list-separator element is only processed in inherit-list-separator</summary>
    </doc:pattern><xsl:template match="fo:index-page-citation-list-separator"/><doc:pattern id="id-index-page-citation-list-separator-inherit" match="fo:index-page-citation-list-separator">
        <summary>Converts fo:index-page-citation-list-separator element to @list-separator attribute</summary>
    </doc:pattern><xsl:template match="fo:index-page-citation-list-separator" mode="inherit-list-separator">
        <xsl:attribute name="list-separator">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template><doc:pattern id="id-index-key-reference" match="fo:index-key-reference">
        <summary>Converts fo:index-key-reference element to rx:index-item</summary>
    </doc:pattern><xsl:template match="fo:index-key-reference">
        <xsl:element name="rx:index-item">
            <xsl:apply-templates select="@ref-index-key"/>
            <xsl:if test="@page-number-treatment | ancestor-or-self::*/@page-number-treatment">
                <xsl:apply-templates select="(@page-number-treatment | ancestor-or-self::*/@page-number-treatment)[position()=last()]" mode="inherit-link-back"/>
            </xsl:if>
        </xsl:element>
    </xsl:template><doc:pattern id="id-ref-index-key" match="fo:index-key-reference/@ref-index-key">
        <summary>Converts fo:index-key-reference/@ref-index-key attribute to rx:index-item/@ref-key</summary>
    </doc:pattern><xsl:template match="fo:index-key-reference/@ref-index-key">
        <xsl:attribute name="ref-key">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template><doc:pattern id="id-merge-subsequent-page-numbers" match="@merge-sequential-page-numbers">
        <summary>@merge-sequential-page-numbers attribute is only processed in inherit-merge-subsequent-page-numbers mode</summary>
    </doc:pattern><xsl:template match="@merge-sequential-page-numbers"/><doc:pattern id="id-merge-subsequent-page-numbers-inherit" match="@merge-sequential-page-numbers">
        <summary>Converts @merge-sequential-page-numbers attribute to @merge-subsequent-page-numbers</summary>
    </doc:pattern><xsl:template match="@merge-sequential-page-numbers" mode="inherit-merge-subsequent-page-numbers">
        <xsl:attribute name="merge-subsequent-page-numbers">
            <xsl:choose>
                <xsl:when test=". = 'merge'">true</xsl:when>
                <xsl:when test=". = 'leave-separate'">false</xsl:when>
                <xsl:otherwise>
                    <xsl:message>Invalid value '<xsl:value-of select="."/>' of '@merge-sequential-page-numbers'. Default value 'true' used.</xsl:message>
                    <xsl:text>true</xsl:text>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:attribute>
    </xsl:template><doc:pattern id="id-page-number-treatment" match="@page-number-treatment">
        <summary>@page-number-treatment attribute is only processed in inherit-link-back mode</summary>
    </doc:pattern><xsl:template match="@page-number-treatment"/><doc:pattern id="id-page-number-treatment-inherit" match="@page-number-treatment">
        <summary>Converts @page-number-treatment attribute to @link-back in inherit mode</summary>
    </doc:pattern><xsl:template match="@page-number-treatment" mode="inherit-link-back">
        <xsl:attribute name="link-back">
            <xsl:choose>
                <xsl:when test=". = 'link'">true</xsl:when>
                <xsl:when test=". = 'no-link'">false</xsl:when>
                <xsl:otherwise>
                    <xsl:message>Invalid value '<xsl:value-of select="."/>' of '@page-number-treatment'. Default value 'false' used.</xsl:message>
                    <xsl:text>false</xsl:text>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:attribute>
    </xsl:template>
    <!--last-page-number-ref-xsl11-to-rx.xsl part
    -->
    <doc:pattern id="id-page-number-citation-last" match="fo:page-number-citation-last">
        <summary>Converts fo:page-number-citation-last element to rx:page-number-citation-last with keeping its attributes</summary>
    </doc:pattern><xsl:template match="fo:page-number-citation-last">
        <xsl:element name="rx:page-number-citation-last">
            <xsl:apply-templates select="@ref-id"/>
            <xsl:value-of select="."/>
        </xsl:element>        
    </xsl:template>
    <!--change-bars-xsl11-to-rx.xsl part
    -->
    <doc:pattern id="id-change-bar-begin" match="fo:change-bar-begin">
        <summary>Converts fo:change-bar-begin element to rx:change-bar-begin with keeping its attributes</summary>
    </doc:pattern><xsl:template match="fo:change-bar-begin">
        <xsl:element name="rx:change-bar-begin">
            <xsl:apply-templates select="@*"/>
            <xsl:value-of select="."/>
        </xsl:element>        
    </xsl:template><doc:pattern id="id-change-bar-end" match="fo:change-bar-end">
        <summary>Converts fo:change-bar-end element to rx:change-bar-end with keeping its attributes</summary>
    </doc:pattern><xsl:template match="fo:change-bar-end">
        <xsl:element name="rx:change-bar-end">
            <xsl:apply-templates select="@*"/>
            <xsl:value-of select="."/>
        </xsl:element>        
    </xsl:template>
    
    <doc:pattern id="id-all" match="@*|node()">
        <summary>Maps elements and attributes which do not need a conversion</summary>
    </doc:pattern>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    

    <!-- ==================================== -->
    <!-- fo:folio-preffix and fo:folio-suffix -->
    <!-- ==================================== -->
    <xsl:template match="fo:folio-prefix | fo:folio-suffix"/>

    <xsl:template match="fo:page-number">
      <xsl:call-template name="page_number">
        <xsl:with-param name="page_sequence" select="./ancestor::fo:page-sequence"/>
      </xsl:call-template>
    </xsl:template>

    <xsl:template match="fo:page-number-citation | fo:page-number-citation-last" mode="reference">
      <xsl:call-template name="page_number">
        <xsl:with-param name="page_sequence" select="(key('ids', @ref-id))[1]"/>
      </xsl:call-template>
    </xsl:template>

    <xsl:template name="page_number">
      <xsl:param name="page_sequence"/>
      <!-- folio-prefix -->
      <xsl:apply-templates select="$page_sequence/fo:folio-prefix" mode="reference"/>
      <!-- folio-number -->
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
      <!-- folio-suffix -->
      <xsl:apply-templates select="$page_sequence/fo:folio-suffix" mode="reference"/>
    </xsl:template>

    <xsl:template match="fo:folio-prefix | fo:folio-suffix" mode="reference">
      <xsl:apply-templates select="@*|node()[local-name() != 'page-number' and
                                             local-name() != 'page-number-citation' and
                                             local-name() != 'page-number-citation-last']" />
    </xsl:template>

    <doc:pattern id="id-ignored-elements" match="fo:flow-map | fo:page-sequence-wrapper
    							     | fo:flow-assignment
                                                             | fo:flow-source-list
                                                             | fo:flow-target-list
                                                             | fo:flow-name-specifier
                                                             | fo:region-name-specifier
                                                             | @allowed-height-scale
                                                             | @allowed-width-scale
                                                             | fo:index-page-number-prefix
                                                             | fo:index-page-number-suffix
                                                             | @index-class
                                                             | @merge-ranges-across-index-key-references
                                                             | @merge-pages-across-index-key-references">
        <summary>The elements 
          fo:flow-map
          | fo:page-sequence-wrapper
          | fo:flow-assignment
          | fo:flow-source-list
          | fo:flow-target-list
          | fo:flow-name-specifier
          | fo:region-name-specifier
          | @allowed-height-scale
          | @allowed-width-scale
          | fo:index-page-number-prefix
          | fo:index-page-number-suffix
          | @index-class
          | @merge-ranges-across-index-key-references
          | @merge-pages-across-index-key-references
            will be ignored since there is no correspondence in RenderX extensions for them</summary>
    </doc:pattern>
    <xsl:template match="fo:flow-map | fo:page-sequence-wrapper
    				     | fo:flow-assignment
                                     | fo:flow-source-list
                                     | fo:flow-target-list
                                     | fo:flow-name-specifier
                                     | fo:region-name-specifier
                                     | @allowed-height-scale
                                     | @allowed-width-scale
                                     | fo:index-page-number-prefix
                                     | fo:index-page-number-suffix
                                     | @index-class
                                     | @merge-ranges-across-index-key-references
                                     | @merge-pages-across-index-key-references"/>
    
</xsl:stylesheet>


