--- /dev/null
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:exsl="http://exslt.org/common"
+ xmlns:rng="http://relaxng.org/ns/structure/1.0"
+ xmlns:doc="http://nwalsh.com/xmlns/schema-doc/"
+ xmlns:ctrl="http://nwalsh.com/xmlns/schema-control/"
+ version="1.0">
+
+<!-- attempts, and currently fails, to produce a DTD -->
+
+<xsl:output method="text"/>
+<xsl:strip-space elements="*"/>
+
+<xsl:variable name="start" select="/rng:grammar/rng:start"/>
+
+<xsl:template match="/">
+ <xsl:variable name="trimmed">
+ <xsl:apply-templates mode="trim"/>
+ </xsl:variable>
+
+ <xsl:variable name="cleaned">
+ <xsl:apply-templates select="exsl:node-set($trimmed)/*" mode="cleanup"/>
+ </xsl:variable>
+
+ <xsl:apply-templates select="exsl:node-set($cleaned)/*"/>
+</xsl:template>
+
+<xsl:key name="defs" match="rng:define" use="@name"/>
+
+<xsl:template match="rng:div">
+ <xsl:apply-templates select="rng:define"/>
+</xsl:template>
+
+<xsl:template match="ctrl:alternate-define"/>
+
+<xsl:template match="rng:define[@name='db.info.titlereq']"/>
+<xsl:template match="rng:define[@name='db.info.titleonly']"/>
+<xsl:template match="rng:define[@name='db.info.titleonlyreq']"/>
+<xsl:template match="rng:define[@name='db.info.titleforbidden']"/>
+
+<xsl:template match="rng:define">
+ <xsl:apply-templates select="rng:element"/>
+</xsl:template>
+
+<xsl:template match="rng:element">
+ <xsl:if test="@name">
+ <xsl:variable name="name" select="@name"/>
+ <xsl:variable name="defname" select="ancestor::rng:define/@name"/>
+
+ <!--
+ <xsl:message>
+ <xsl:value-of select="@name"/>
+ <xsl:text> (</xsl:text>
+ <xsl:value-of select="../@name"/>
+ <xsl:text>)</xsl:text>
+ </xsl:message>
+ -->
+ <xsl:text><!ELEMENT </xsl:text>
+ <xsl:value-of select="@name"/>
+ <xsl:text> </xsl:text>
+ <xsl:apply-templates select="doc:content-model" mode="model"/>
+ <xsl:text>> </xsl:text>
+
+ <xsl:text><!ATTLIST </xsl:text>
+ <xsl:value-of select="@name"/>
+ <xsl:text> </xsl:text>
+
+ <xsl:if test="$start//rng:ref[@name = $defname]">
+ <xsl:text>	xmlns	CDATA #FIXED "http://docbook.org/docbook-ng" </xsl:text>
+ <xsl:text>	version	CDATA	#IMPLIED </xsl:text>
+ </xsl:if>
+
+ <xsl:apply-templates select="doc:attributes" mode="attlist"/>
+ <xsl:text>> </xsl:text>
+ </xsl:if>
+</xsl:template>
+
+<!-- ====================================================================== -->
+<!-- doc:content-model -->
+
+<xsl:template match="doc:content-model" mode="model">
+ <xsl:choose>
+ <xsl:when test="rng:choice|rng:oneOrMore|rng:zeroOrMore|rng:interleave|rng:group">
+ <xsl:apply-templates mode="model"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>(</xsl:text>
+ <xsl:apply-templates mode="model"/>
+ <xsl:text>)</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="rng:group" mode="model">
+ <xsl:text>(</xsl:text>
+ <xsl:for-each select="*">
+ <xsl:apply-templates select="." mode="model"/>
+ <xsl:if test="position() != last()">, </xsl:if>
+ </xsl:for-each>
+ <xsl:text>)</xsl:text>
+</xsl:template>
+
+<xsl:template match="rng:choice" mode="model">
+ <xsl:text>(</xsl:text>
+ <xsl:for-each select="*">
+ <xsl:apply-templates select="." mode="model"/>
+ <xsl:if test="position() != last()"> | </xsl:if>
+ </xsl:for-each>
+ <xsl:text>)</xsl:text>
+</xsl:template>
+
+<xsl:template match="rng:interleave" mode="model">
+ <xsl:text>(</xsl:text>
+ <xsl:for-each select="*">
+ <xsl:apply-templates select="." mode="model"/>
+ <xsl:if test="position() != last()">, </xsl:if>
+ </xsl:for-each>
+ <xsl:text>)</xsl:text>
+</xsl:template>
+
+<xsl:template match="rng:zeroOrMore" mode="model">
+ <xsl:text>(</xsl:text>
+ <xsl:for-each select="*">
+ <xsl:apply-templates select="." mode="model"/>
+ <xsl:if test="position() != last()"> | </xsl:if>
+ </xsl:for-each>
+ <xsl:text>)*</xsl:text>
+</xsl:template>
+
+<xsl:template match="rng:oneOrMore" mode="model">
+ <xsl:text>(</xsl:text>
+ <xsl:for-each select="*">
+ <xsl:apply-templates select="." mode="model"/>
+ <xsl:if test="position() != last()"> | </xsl:if>
+ </xsl:for-each>
+ <xsl:text>)+</xsl:text>
+</xsl:template>
+
+<xsl:template match="rng:optional" mode="model">
+ <xsl:apply-templates mode="model"/>
+ <xsl:text>?</xsl:text>
+</xsl:template>
+
+<xsl:template match="rng:ref" mode="model">
+ <xsl:variable name="def" select="key('defs', @name)"/>
+ <xsl:value-of select="$def/rng:element/@name"/>
+</xsl:template>
+
+<xsl:template match="rng:text" mode="model">
+ <xsl:text>#PCDATA</xsl:text>
+</xsl:template>
+
+<xsl:template match="rng:empty" mode="model">
+ <xsl:text>EMPTY</xsl:text>
+</xsl:template>
+
+<xsl:template match="rng:data" mode="model">
+ <xsl:message>Using #PCDATA instead of <xsl:value-of select="@type"/></xsl:message>
+ <xsl:text>#PCDATA</xsl:text>
+</xsl:template>
+
+<!-- ====================================================================== -->
+<!-- doc:attributes -->
+
+<xsl:template match="doc:attributes" mode="attlist">
+ <xsl:apply-templates mode="attlist"/>
+</xsl:template>
+
+<xsl:template match="rng:attribute" mode="attlist">
+ <xsl:text>	</xsl:text>
+ <xsl:value-of select="@name"/>
+
+ <xsl:text>	</xsl:text>
+ <xsl:if test="string-length(@name) < 8">
+ <xsl:text>	</xsl:text>
+ </xsl:if>
+
+ <xsl:choose>
+ <xsl:when test="rng:data">
+ <xsl:choose>
+ <xsl:when test="rng:data/@type = 'integer'">CDATA</xsl:when>
+ <xsl:otherwise><xsl:value-of select="rng:data/@type"/></xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="rng:choice">
+ <xsl:text>(</xsl:text>
+ <xsl:for-each select="rng:choice/rng:value">
+ <xsl:value-of select="."/>
+ <xsl:if test="position() != last()">|</xsl:if>
+ </xsl:for-each>
+ <xsl:text>)</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>CDATA</xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:text>	</xsl:text>
+ <xsl:choose>
+ <xsl:when test="ancestor::rng:optional">
+ <xsl:text>#IMPLIED</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>#REQUIRED</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:text> </xsl:text>
+</xsl:template>
+
+<xsl:template match="rng:interleave|rng:optional" mode="attlist">
+ <xsl:apply-templates mode="attlist"/>
+</xsl:template>
+
+<!-- ====================================================================== -->
+<!-- trim -->
+
+<xsl:template match="rng:ref[@name='indexterm.startofrange']" mode="trim"/>
+<xsl:template match="rng:ref[@name='indexterm.endofrange']" mode="trim"/>
+<xsl:template match="rng:ref[@name='html.informaltable']" mode="trim"/>
+<xsl:template match="rng:ref[@name='html.table']" mode="trim"/>
+<xsl:template match="rng:ref[@name='any.svg']" mode="trim"/>
+<xsl:template match="rng:ref[@name='any.mml']" mode="trim"/>
+<xsl:template match="rng:data[preceding-sibling::rng:data]" mode="trim"/>
+
+<xsl:template match="rng:define[@name='indexterm.startofrange']" mode="trim"/>
+<xsl:template match="rng:define[@name='indexterm.endofrange']" mode="trim"/>
+<xsl:template match="rng:define[@name='html.informaltable']" mode="trim"/>
+<xsl:template match="rng:define[@name='html.table']" mode="trim"/>
+<xsl:template match="rng:define[@name='html.thead']" mode="trim"/>
+<xsl:template match="rng:define[@name='html.tbody']" mode="trim"/>
+<xsl:template match="rng:define[@name='html.tfoot']" mode="trim"/>
+<xsl:template match="rng:define[@name='any.svg']" mode="trim"/>
+<xsl:template match="rng:define[@name='any.mml']" mode="trim"/>
+<xsl:template match="rng:define[@name='text.phrase']" mode="trim"/>
+
+<xsl:template match="*" mode="trim">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="trim"/>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="comment()|processing-instruction()|text()" mode="trim">
+ <xsl:copy/>
+</xsl:template>
+
+<!-- ====================================================================== -->
+<!-- cleanup -->
+
+<xsl:template match="doc:content-model[count(*) = 1 and rng:text]" mode="cleanup">
+ <doc:content-model>
+ <rng:zeroOrMore>
+ <rng:text/>
+ </rng:zeroOrMore>
+ </doc:content-model>
+</xsl:template>
+
+<xsl:template match="doc:content-model[.//rng:text]" mode="cleanup">
+ <xsl:variable name="children">
+ <xsl:copy-of select=".//rng:ref"/>
+ </xsl:variable>
+
+ <doc:content-model>
+ <rng:zeroOrMore>
+ <rng:text/>
+ <xsl:for-each select="exsl:node-set($children)/*">
+ <xsl:variable name="name" select="@name"/>
+ <xsl:if test="not(preceding-sibling::rng:ref[@name = $name])">
+ <xsl:copy-of select="."/>
+ </xsl:if>
+ </xsl:for-each>
+ </rng:zeroOrMore>
+ </doc:content-model>
+</xsl:template>
+
+<xsl:template match="*" mode="cleanup">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="cleanup"/>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="comment()|processing-instruction()|text()" mode="cleanup">
+ <xsl:copy/>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:rng="http://relaxng.org/ns/structure/1.0"
+ xmlns:ctrl="http://nwalsh.com/xmlns/schema-control/"
+ version="1.0">
+
+<xsl:key name="defs" match="rng:define" use="@name"/>
+<xsl:key name="ctrlname" match="ctrl:other-attribute" use="@name"/>
+<xsl:key name="ctrlenum" match="ctrl:other-attribute" use="@enum-name"/>
+<xsl:key name="ctrlother" match="ctrl:other-attribute" use="@other-name"/>
+
+<xsl:template match="rng:define" priority="200">
+ <xsl:choose>
+ <xsl:when test="key('ctrlenum', @name)"/>
+ <xsl:when test="key('ctrlother', @name)"/>
+ <xsl:when test="key('ctrlname', @name)">
+ <xsl:message>Simplify attributes: <xsl:value-of select="@name"/></xsl:message>
+ <xsl:variable name="otherattr" select="key('ctrlname', @name)"/>
+ <rng:define name="{@name}">
+ <rng:optional>
+ <rng:attribute name="{$otherattr/@other-name}"/>
+ </rng:optional>
+ <rng:optional>
+ <rng:attribute name="{$otherattr/@enum-name}">
+ <choice>
+ <xsl:copy-of select="key('defs', $otherattr/@enum-name)//rng:value"/>
+ <xsl:copy-of select="key('defs', $otherattr/@other-name)//rng:value"/>
+ </choice>
+ </rng:attribute>
+ </rng:optional>
+ </rng:define>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="rng:choice[rng:ref[@name='docbook.text']]" priority="200">
+ <xsl:message>Simplify choice with text</xsl:message>
+ <rng:zeroOrMore>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </rng:zeroOrMore>
+</xsl:template>
+
+<xsl:template match="*">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="comment()|processing-instruction()|text()">
+ <xsl:copy/>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:exsl="http://exslt.org/common"
+ xmlns:set="http://exslt.org/sets"
+ xmlns:rng="http://relaxng.org/ns/structure/1.0"
+ xmlns:ctrl="http://nwalsh.com/xmlns/schema-control/"
+ xmlns:doc="http://nwalsh.com/xmlns/schema-doc/"
+ xmlns:s="http://www.ascc.net/xml/schematron"
+ exclude-result-prefixes="exsl ctrl s set"
+ version="1.0">
+
+<!-- This stylesheet does the same things as rngdocxml.xsl, except that it -->
+<!-- does it in several discrete passes. This works around two problems: -->
+<!-- 1. Running rngdocxml.xsl under saxon is tediously slow (maybe because -->
+<!-- of object creation issues?) and 2. xsltproc has a bug in key() -->
+
+ <xsl:output method="xml" encoding="utf-8" indent="yes"/>
+ <xsl:strip-space elements="*"/>
+
+ <xsl:param name="pass" select="'group'"/>
+
+ <xsl:key name="defs" match="rng:define" use="@name"/>
+
+ <xsl:template match="/">
+ <xsl:variable name="grouped">
+ <xsl:message>Add groups</xsl:message>
+ <xsl:apply-templates select="/" mode="group"/>
+ </xsl:variable>
+
+ <xsl:variable name="expanded">
+ <xsl:message>Expand content models</xsl:message>
+ <xsl:call-template name="expand">
+ <xsl:with-param name="root" select="exsl:node-set($grouped)"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="classified">
+ <xsl:message>Classify element content</xsl:message>
+ <xsl:call-template name="classify">
+ <xsl:with-param name="root" select="exsl:node-set($expanded)"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="flattened">
+ <xsl:message>Flatten nested choices</xsl:message>
+ <xsl:call-template name="flatten">
+ <xsl:with-param name="root" select="exsl:node-set($classified)"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:copy-of select="$flattened"/>
+ </xsl:template>
+
+ <xsl:template match="/FOOBAR">
+ <xsl:choose>
+ <xsl:when test="$pass = 'group'">
+ <xsl:message>Add groups</xsl:message>
+ <xsl:apply-templates select="/" mode="group"/>
+ </xsl:when>
+
+ <xsl:when test="$pass = 'expand'">
+ <xsl:message>Expand content models</xsl:message>
+ <xsl:apply-templates select="/" mode="expand"/>
+ </xsl:when>
+
+ <xsl:when test="$pass = 'classify'">
+ <xsl:message>Classify element content</xsl:message>
+ <xsl:apply-templates select="/" mode="classify"/>
+ </xsl:when>
+
+ <xsl:when test="$pass = 'flatten'">
+ <xsl:message>Flatten nested choices</xsl:message>
+ <xsl:apply-templates select="/" mode="flatten"/>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:message terminate="yes">Bad pass!</xsl:message>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- ====================================================================== -->
+ <!-- group -->
+
+ <xsl:template match="rng:grammar" mode="group">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:attribute name="next-pass">expand</xsl:attribute>
+ <xsl:apply-templates mode="group"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="rng:define[count(*) > 1]
+ |rng:zeroOrMore[count(*) > 1]
+ |rng:oneOrMore[count(*) > 1]"
+ mode="group">
+ <xsl:variable name="refs">
+ <xsl:text>0</xsl:text>
+ <xsl:for-each select=".//rng:ref">
+ <xsl:if test="key('defs',@name)/rng:element">1</xsl:if>
+ </xsl:for-each>
+ <xsl:if test="count(rng:attribute|rng:optional/rng:attribute) > 0">1</xsl:if>
+ </xsl:variable>
+
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+
+ <xsl:choose>
+ <xsl:when test="$refs > 0">
+ <rng:group>
+ <xsl:apply-templates mode="group"/>
+ </rng:group>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates mode="group"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="*" mode="group">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="group"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="comment()|processing-instruction()|text()" mode="group">
+ <xsl:copy/>
+ </xsl:template>
+
+ <!-- ====================================================================== -->
+ <!-- expand -->
+
+ <xsl:template name="expand">
+ <xsl:param name="root" select="/"/>
+
+ <xsl:variable name="expanded">
+ <xsl:apply-templates select="$root" mode="expand"/>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="exsl:node-set($expanded)/rng:grammar/@next-pass='expand'">
+ <xsl:call-template name="expand">
+ <xsl:with-param name="root" select="exsl:node-set($expanded)"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="$expanded"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="/" mode="expand">
+ <xsl:variable name="canExpand">
+ <xsl:apply-templates select="/" mode="expandTest"/>
+ </xsl:variable>
+
+ <xsl:message>
+ <xsl:value-of select="string-length($canExpand)"/>
+ <xsl:text> patterns to expand</xsl:text>
+ </xsl:message>
+
+ <xsl:choose>
+ <xsl:when test="string-length($canExpand) = 0">
+ <xsl:apply-templates mode="no-expand"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates mode="expand"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="/" mode="expandTest">
+ <xsl:for-each select="//rng:ref">
+ <xsl:variable name="name" select="@name"/>
+ <xsl:variable name="ref" select="key('defs', @name)"/>
+
+ <xsl:choose>
+ <xsl:when test="ancestor::rng:define[@name=$name]">
+ <!-- don't expand recursively -->
+ </xsl:when>
+ <xsl:when test="$ref and $ref/rng:element">
+ <!-- don't expand element patterns -->
+ </xsl:when>
+ <xsl:when test="$ref and $ref/rng:empty">
+ <!-- don't expand empty patterns -->
+ </xsl:when>
+ <xsl:when test="$ref">1</xsl:when>
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="rng:grammar" mode="expand">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:attribute name="next-pass">expand</xsl:attribute>
+ <xsl:apply-templates mode="expand"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="rng:ref" priority="2" mode="expand">
+ <xsl:variable name="name" select="@name"/>
+ <xsl:variable name="ref" select="key('defs', @name)"/>
+
+ <xsl:choose>
+ <xsl:when test="$ref and ancestor::rng:define[@name=$name]">
+ <!-- don't expand recursively -->
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="expand"/>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:when test="$ref and $ref/rng:element">
+ <!-- don't expand element patterns -->
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="expand"/>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:when test="$ref and $ref/rng:empty">
+ <!-- just discard it -->
+ </xsl:when>
+ <xsl:when test="$ref">
+ <xsl:copy-of select="$ref/*"/>
+
+ <!--
+ <xsl:if test="@name = 'area.units-other.attributes'">
+ <xsl:message>
+ <xsl:text>Expanding </xsl:text>
+ <xsl:value-of select="@name"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="name($ref/*[1])"/>
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="name($ref)"/>
+ </xsl:message>
+ </xsl:if>
+ -->
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="expand"/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="rng:element" mode="expand">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="expand"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="*" mode="expand">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="expand"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="comment()|processing-instruction()|text()" mode="expand">
+ <xsl:copy/>
+ </xsl:template>
+
+ <!-- ======================================== -->
+
+ <xsl:template match="rng:grammar" mode="no-expand">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:attribute name="next-pass">classify</xsl:attribute>
+ <xsl:apply-templates mode="no-expand"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="*" mode="no-expand">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="no-expand"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="comment()|processing-instruction()|text()" mode="no-expand">
+ <xsl:copy/>
+ </xsl:template>
+
+ <!-- ====================================================================== -->
+
+ <xsl:template name="classify">
+ <xsl:param name="root" select="/"/>
+ <xsl:apply-templates select="$root" mode="classify"/>
+ </xsl:template>
+
+ <xsl:template match="rng:grammar" mode="classify">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:attribute name="next-pass">flatten</xsl:attribute>
+ <xsl:apply-templates mode="classify"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="rng:element|rng:start" mode="classify">
+ <xsl:variable name="attr"
+ select="*[self::rng:ref[key('defs',@name)/rng:attribute]
+ |self::rng:attribute
+ |.//rng:ref[key('defs',@name)/rng:attribute]
+ |.//rng:attribute]"/>
+ <xsl:variable name="rules" select="s:*"/>
+ <xsl:variable name="cmod" select="set:difference(*,$attr|rng:notAllowed|$rules)"/>
+
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+
+ <doc:attributes>
+ <xsl:copy-of select="$attr"/>
+ </doc:attributes>
+
+ <doc:content-model>
+ <xsl:choose>
+ <xsl:when test="count($cmod) > 1">
+ <rng:group>
+ <xsl:copy-of select="$cmod"/>
+ </rng:group>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="$cmod"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </doc:content-model>
+
+ <xsl:if test="$rules">
+ <doc:rules>
+ <xsl:copy-of select="$rules"/>
+ </doc:rules>
+ </xsl:if>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="*" mode="classify">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="classify"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="comment()|processing-instruction()|text()" mode="classify">
+ <xsl:copy/>
+ </xsl:template>
+
+ <!-- ====================================================================== -->
+
+ <xsl:template name="flatten">
+ <xsl:param name="root" select="/"/>
+
+ <xsl:variable name="flattened">
+ <xsl:apply-templates select="$root" mode="flatten"/>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="exsl:node-set($flattened)/rng:grammar/@next-pass='flatten'">
+ <xsl:call-template name="flatten">
+ <xsl:with-param name="root" select="exsl:node-set($flattened)"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="$flattened"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="/" mode="flatten">
+ <xsl:variable name="canFlatten">
+ <xsl:apply-templates select="/" mode="flattenTest"/>
+ </xsl:variable>
+
+ <xsl:message>
+ <xsl:value-of select="$canFlatten"/>
+ <xsl:text> patterns to flatten</xsl:text>
+ </xsl:message>
+
+ <xsl:choose>
+ <xsl:when test="$canFlatten = 0">
+ <xsl:apply-templates mode="no-flatten"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates mode="flatten"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="/" mode="flattenTest">
+ <xsl:value-of select="count(//doc:content-model//rng:choice/rng:choice
+ |//doc:content-model//rng:zeroOrMore/rng:choice
+ |//doc:content-model//rng:oneOrMore/rng:choice
+ |//doc:content-model//rng:zeroOrMore/rng:zeroOrMore
+ |//doc:content-model//rng:oneOrMore/rng:oneOrMore)"/>
+ </xsl:template>
+
+ <xsl:template match="rng:grammar" mode="flatten">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:attribute name="next-pass">flatten</xsl:attribute>
+ <xsl:apply-templates mode="flatten"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="rng:group" mode="flatten">
+ <xsl:choose>
+ <xsl:when test="ancestor::doc:attributes
+ and count(*) = count(rng:optional[rng:attribute])">
+ <xsl:apply-templates mode="flatten"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="flatten"/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="doc:content-model//rng:choice/rng:choice
+ |doc:content-model//rng:zeroOrMore/rng:choice
+ |doc:content-model//rng:oneOrMore/rng:choice
+ |doc:content-model//rng:zeroOrMore/rng:zeroOrMore
+ |doc:content-model//rng:oneOrMore/rng:oneOrMore"
+ mode="flatten">
+ <xsl:apply-templates mode="flatten"/>
+ </xsl:template>
+
+ <xsl:template match="rng:notAllowed" mode="flatten">
+ <xsl:choose>
+ <xsl:when test="parent::rng:choice|parent::rng:zeroOrMore|parent::rng:oneOrMore">
+ <!-- suppress -->
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="flatten"/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="rng:ref" mode="flatten">
+ <xsl:variable name="name" select="@name"/>
+ <xsl:choose>
+ <xsl:when test="preceding-sibling::rng:ref[@name = $name]">
+ <!-- suppress -->
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="flatten"/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="*" mode="flatten">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="flatten"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="comment()|processing-instruction()|text()" mode="flatten">
+ <xsl:copy/>
+ </xsl:template>
+
+ <!-- ======================================== -->
+
+ <xsl:template match="rng:grammar" mode="no-flatten">
+ <xsl:copy>
+ <xsl:copy-of select="@*[name(.) != 'next-pass']"/>
+ <xsl:apply-templates mode="no-flatten"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="*" mode="no-flatten">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="no-flatten"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="comment()|processing-instruction()|text()" mode="no-flatten">
+ <xsl:copy/>
+ </xsl:template>
+
+ <!-- ====================================================================== -->
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:exsl="http://exslt.org/common"
+ xmlns:db = "http://docbook.org/docbook-ng"
+ exclude-result-prefixes="exsl db"
+ version="1.0">
+
+<xsl:import href="db4-upgrade.xsl"/>
+
+<xsl:template match="slidesinfo"
+ priority="200">
+ <info>
+ <xsl:call-template name="copy.attributes"/>
+
+ <!-- titles can be inside or outside or both. fix that -->
+ <xsl:choose>
+ <xsl:when test="title and following-sibling::title">
+ <xsl:if test="title != following-sibling::title">
+ <xsl:message>
+ <xsl:text>Check </xsl:text>
+ <xsl:value-of select="name(..)"/>
+ <xsl:text> title.</xsl:text>
+ </xsl:message>
+ </xsl:if>
+ <xsl:apply-templates select="title" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="title">
+ <xsl:apply-templates select="title" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="following-sibling::title">
+ <xsl:apply-templates select="following-sibling::title" mode="copy"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:message>
+ <xsl:text>Check </xsl:text>
+ <xsl:value-of select="name(..)"/>
+ <xsl:text>: no title.</xsl:text>
+ </xsl:message>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:choose>
+ <xsl:when test="titleabbrev and following-sibling::titleabbrev">
+ <xsl:if test="titleabbrev != following-sibling::titleabbrev">
+ <xsl:message>
+ <xsl:text>Check </xsl:text>
+ <xsl:value-of select="name(..)"/>
+ <xsl:text> titleabbrev.</xsl:text>
+ </xsl:message>
+ </xsl:if>
+ <xsl:apply-templates select="titleabbrev" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="titleabbrev">
+ <xsl:apply-templates select="titleabbrev" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="following-sibling::titleabbrev">
+ <xsl:apply-templates select="following-sibling::titleabbrev" mode="copy"/>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:choose>
+ <xsl:when test="subtitle and following-sibling::subtitle">
+ <xsl:if test="subtitle != following-sibling::subtitle">
+ <xsl:message>
+ <xsl:text>Check </xsl:text>
+ <xsl:value-of select="name(..)"/>
+ <xsl:text> subtitle.</xsl:text>
+ </xsl:message>
+ </xsl:if>
+ <xsl:apply-templates select="subtitle" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="subtitle">
+ <xsl:apply-templates select="subtitle" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="following-sibling::subtitle">
+ <xsl:apply-templates select="following-sibling::subtitle" mode="copy"/>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:apply-templates/>
+ </info>
+</xsl:template>
+
+<xsl:template match="foil/title|foilgroup/title
+ |foil/subtitle|foilgroup/subtitle
+ |foil/titleabbrev|foilgroup/titleabbrev" priority="200">
+ <xsl:apply-templates select="." mode="copy"/>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:rng="http://relaxng.org/ns/structure/1.0"
+ version="1.0">
+
+ <xsl:output method="xml" encoding="utf-8" indent="yes"/>
+ <xsl:strip-space elements="*"/>
+
+ <xsl:template match="/">
+ <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="rng:div" priority="100">
+ <xsl:if test="rng:*[not(@unused)]">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="rng:*" priority="50">
+ <xsl:if test="not(@unused)">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="*">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="comment()|processing-instruction()|text()">
+ <xsl:copy/>
+ </xsl:template>
+
+</xsl:stylesheet>