--- /dev/null
+<p:declare-step xmlns:p="http://www.w3.org/ns/xproc"
+ xmlns:c="http://www.w3.org/ns/xproc-step"
+ xmlns:cx="http://xmlcalabash.com/ns/extensions"
+ name="main" version='1.0' >
+
+ <p:input port="source">
+ <p:document href="../../docbook/dtd.rng"/>
+ </p:input>
+ <p:input port="parameters" kind="parameter"/>
+ <p:output port="result"/>
+ <p:serialization port="result" method="text"/>
+
+ <p:option name="debug" select="0"/>
+ <p:option name="override" select="'src/override-docbook.xml'"/>
+
+<!-- ============================================================ -->
+
+ <p:declare-step type="cx:tee" name="teemain">
+ <p:input port="source" sequence="true" primary="true"/>
+ <p:output port="result" sequence="true" primary="true">
+ <p:pipe step="identity" port="result"/>
+ </p:output>
+ <p:option name="href" required="true"/>
+ <p:option name="debug" select="0"/>
+
+ <p:choose>
+ <p:when test="$debug != 0">
+ <p:store name="saving-debugging-output" method="xml" indent="true">
+ <p:with-option name="href" select="$href"/>
+ </p:store>
+ </p:when>
+ <p:otherwise>
+ <p:sink name="discarding-debugging-output"/>
+ </p:otherwise>
+ </p:choose>
+
+ <p:identity name="identity">
+ <p:input port="source">
+ <p:pipe step="teemain" port="source"/>
+ </p:input>
+ </p:identity>
+ </p:declare-step>
+
+<!-- ============================================================ -->
+
+ <p:variable name="override.xml" select="resolve-uri($override)"/>
+
+<!-- ============================================================ -->
+
+ <cx:tee href="output-of-input.xml">
+ <p:with-option name="debug" select="$debug"/>
+ </cx:tee>
+
+ <p:xslt name="rng2dtx">
+ <p:input port="stylesheet">
+ <p:document href="style/rng2dtx.xsl"/>
+ </p:input>
+ </p:xslt>
+
+ <cx:tee href="output-of-rng2dtx.xml">
+ <p:with-option name="debug" select="$debug"/>
+ </cx:tee>
+
+ <p:xslt name="override">
+ <p:input port="stylesheet">
+ <p:document href="style/override.xsl"/>
+ </p:input>
+ <p:with-param name="override.xml" select="$override.xml"/>
+ </p:xslt>
+
+ <cx:tee href="output-of-override.xml">
+ <p:with-option name="debug" select="$debug"/>
+ </cx:tee>
+
+ <cx:until-unchanged name="remove-choice">
+ <p:xslt name="attr-remove-choice">
+ <p:input port="stylesheet">
+ <p:document href="style/attr-remove-choice.xsl"/>
+ </p:input>
+ </p:xslt>
+ </cx:until-unchanged>
+
+ <cx:tee href="output-of-attr-remove-choice.xml">
+ <p:with-option name="debug" select="$debug"/>
+ </cx:tee>
+
+ <cx:until-unchanged name="remove-unused">
+ <p:xslt name="attr-remove-unused">
+ <p:input port="stylesheet">
+ <p:document href="style/attr-remove-unused.xsl"/>
+ </p:input>
+ </p:xslt>
+ </cx:until-unchanged>
+
+ <cx:tee href="output-of-attr-remove-unused.xml">
+ <p:with-option name="debug" select="$debug"/>
+ </cx:tee>
+
+ <p:xslt name="attr-optional-to-ref">
+ <p:input port="stylesheet">
+ <p:document href="style/attr-optional-to-ref.xsl"/>
+ </p:input>
+ </p:xslt>
+
+ <cx:tee href="output-of-attr-optional-to-ref.xml">
+ <p:with-option name="debug" select="$debug"/>
+ </cx:tee>
+
+ <cx:until-unchanged name="to-attref">
+ <p:xslt name="ref-to-attref">
+ <p:input port="stylesheet">
+ <p:document href="style/ref-to-attref.xsl"/>
+ </p:input>
+ </p:xslt>
+ </cx:until-unchanged>
+
+ <cx:tee href="output-of-ref-to-attref.xml">
+ <p:with-option name="debug" select="$debug"/>
+ </cx:tee>
+
+ <cx:until-unchanged name="flatten">
+ <p:xslt name="flatten-attref">
+ <p:input port="stylesheet">
+ <p:document href="style/flatten-attref.xsl"/>
+ </p:input>
+ </p:xslt>
+ </cx:until-unchanged>
+
+ <cx:tee href="output-of-flatten-attref.xml">
+ <p:with-option name="debug" select="$debug"/>
+ </cx:tee>
+
+ <p:xslt name="attr-optional-to-decl">
+ <p:input port="stylesheet">
+ <p:document href="style/attr-optional-to-decl.xsl"/>
+ </p:input>
+ </p:xslt>
+
+ <cx:tee href="output-of-attr-optional-to-decl.xml">
+ <p:with-option name="debug" select="$debug"/>
+ </cx:tee>
+
+ <p:xslt name="multiple-gis">
+ <p:input port="stylesheet">
+ <p:document href="style/multiple-gis.xsl"/>
+ </p:input>
+ </p:xslt>
+
+ <cx:tee href="output-of-multiple-gis.xml">
+ <p:with-option name="debug" select="$debug"/>
+ </cx:tee>
+
+ <p:xslt name="remove-empty-pes">
+ <p:input port="stylesheet">
+ <p:document href="style/remove-empty-pes.xsl"/>
+ </p:input>
+ </p:xslt>
+
+ <cx:tee href="output-of-remove-empty-pes.xml">
+ <p:with-option name="debug" select="$debug"/>
+ </cx:tee>
+
+ <cx:until-unchanged name="pull-up">
+ <p:xslt name="pull-up-text">
+ <p:input port="stylesheet">
+ <p:document href="style/pull-up-text.xsl"/>
+ </p:input>
+ </p:xslt>
+ </cx:until-unchanged>
+
+ <cx:tee href="output-of-pull-up-text.xml">
+ <p:with-option name="debug" select="$debug"/>
+ </cx:tee>
+
+ <cx:until-unchanged name="unwrap">
+ <p:xslt name="unwrap-zeroormore">
+ <p:input port="stylesheet">
+ <p:document href="style/unwrap-zeroormore.xsl"/>
+ </p:input>
+ </p:xslt>
+ </cx:until-unchanged>
+
+ <cx:tee href="output-of-unwrap-zeroormore.xml">
+ <p:with-option name="debug" select="$debug"/>
+ </cx:tee>
+
+ <cx:until-unchanged name="sort">
+ <p:xslt name="sort-pe">
+ <p:input port="stylesheet">
+ <p:document href="style/sort-pes.xsl"/>
+ </p:input>
+ </p:xslt>
+ </cx:until-unchanged>
+
+ <cx:tee href="output-of-sort-pes.xml">
+ <p:with-option name="debug" select="$debug"/>
+ </cx:tee>
+
+ <p:xslt name="dtx2dtd">
+ <p:input port="stylesheet">
+ <p:document href="style/dtx2dtd.xsl"/>
+ </p:input>
+ </p:xslt>
+
+</p:declare-step>
--- /dev/null
+<p:declare-step xmlns:p="http://www.w3.org/ns/xproc"
+ xmlns:c="http://www.w3.org/ns/xproc-step"
+ xmlns:cx="http://xmlcalabash.com/ns/extensions"
+ name="main" version='1.0' >
+
+ <p:input port="source">
+ <p:document href="../../docbook/dtd.rng"/>
+ </p:input>
+ <p:input port="parameters" kind="parameter"/>
+ <p:output port="result"/>
+ <p:serialization port="result" method="text"/>
+
+ <p:option name="debug" select="0"/>
+ <p:option name="override" select="'src/override-docbook.xml'"/>
+
+<!-- ============================================================ -->
+
+ <p:variable name="override.xml" select="resolve-uri($override)"/>
+
+<!-- ============================================================ -->
+
+ <p:xslt name="rng2dtx">
+ <p:input port="stylesheet">
+ <p:document href="style/rng2dtx.xsl"/>
+ </p:input>
+ </p:xslt>
+
+ <p:xslt name="override">
+ <p:input port="stylesheet">
+ <p:document href="style/override.xsl"/>
+ </p:input>
+ <p:with-param name="override.xml" select="$override.xml"/>
+ </p:xslt>
+
+ <cx:until-unchanged name="remove-choice">
+ <p:xslt name="attr-remove-choice">
+ <p:input port="stylesheet">
+ <p:document href="style/attr-remove-choice.xsl"/>
+ </p:input>
+ </p:xslt>
+ </cx:until-unchanged>
+
+ <cx:until-unchanged name="remove-unused">
+ <p:xslt name="attr-remove-unused">
+ <p:input port="stylesheet">
+ <p:document href="style/attr-remove-unused.xsl"/>
+ </p:input>
+ </p:xslt>
+ </cx:until-unchanged>
+
+ <p:xslt name="attr-optional-to-ref">
+ <p:input port="stylesheet">
+ <p:document href="style/attr-optional-to-ref.xsl"/>
+ </p:input>
+ </p:xslt>
+
+ <cx:until-unchanged name="to-attref">
+ <p:xslt name="ref-to-attref">
+ <p:input port="stylesheet">
+ <p:document href="style/ref-to-attref.xsl"/>
+ </p:input>
+ </p:xslt>
+ </cx:until-unchanged>
+
+ <cx:until-unchanged name="flatten">
+ <p:xslt name="flatten-attref">
+ <p:input port="stylesheet">
+ <p:document href="style/flatten-attref.xsl"/>
+ </p:input>
+ </p:xslt>
+ </cx:until-unchanged>
+
+ <p:xslt name="attr-optional-to-decl">
+ <p:input port="stylesheet">
+ <p:document href="style/attr-optional-to-decl.xsl"/>
+ </p:input>
+ </p:xslt>
+
+ <p:xslt name="multiple-gis">
+ <p:input port="stylesheet">
+ <p:document href="style/multiple-gis.xsl"/>
+ </p:input>
+ </p:xslt>
+
+ <p:xslt name="remove-empty-pes">
+ <p:input port="stylesheet">
+ <p:document href="style/remove-empty-pes.xsl"/>
+ </p:input>
+ </p:xslt>
+
+ <cx:until-unchanged name="pull-up">
+ <p:xslt name="pull-up-text">
+ <p:input port="stylesheet">
+ <p:document href="style/pull-up-text.xsl"/>
+ </p:input>
+ </p:xslt>
+ </cx:until-unchanged>
+
+ <cx:until-unchanged name="unwrap">
+ <p:xslt name="unwrap-zeroormore">
+ <p:input port="stylesheet">
+ <p:document href="style/unwrap-zeroormore.xsl"/>
+ </p:input>
+ </p:xslt>
+ </cx:until-unchanged>
+
+ <cx:until-unchanged name="sort">
+ <p:xslt name="sort-pe">
+ <p:input port="stylesheet">
+ <p:document href="style/sort-pes.xsl"/>
+ </p:input>
+ </p:xslt>
+ </cx:until-unchanged>
+
+ <p:xslt name="dtx2dtd">
+ <p:input port="stylesheet">
+ <p:document href="style/dtx2dtd.xsl"/>
+ </p:input>
+ </p:xslt>
+
+</p:declare-step>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<dtd xmlns="http://nwalsh.com/ns/dtd-xml">
+
+ <!-- Fix "any" content -->
+
+ <del-pe name="db._any.attribute"/>
+ <del-element name="db._any"/>
+
+ <!-- Fix indexterm -->
+
+ <ref-rename name="db.indexterm.singular" rename="db.indexterm"/>
+
+ <!-- Fix caption -->
+
+ <ref-rename name="db.html.caption" rename="db.caption"/>
+
+ <!-- Fix limited content model inlines -->
+
+ <del-element name="db._foreignphrase"/>
+ <ref-rename name="db._foreignphrase" rename="db.foreignphrase"/>
+
+ <del-element name="db._emphasis"/>
+ <ref-rename name="db._emphasis" rename="db.emphasis"/>
+
+ <del-element name="db._quote"/>
+ <ref-rename name="db._quote" rename="db.quote"/>
+
+ <del-element name="db._firstterm"/>
+ <ref-rename name="db._firstterm" rename="db.firstterm"/>
+
+ <del-element name="db._glossterm"/>
+ <ref-rename name="db._glossterm" rename="db.glossterm"/>
+
+ <del-element name="db._phrase"/>
+ <ref-rename name="db._phrase" rename="db.phrase"/>
+
+ <!-- Fix SVG and MathML -->
+
+ <ref-rename name="db.imagedata.mathml" rename="db.imagedata"/>
+ <ref-rename name="db.imagedata.svg" rename="db.imagedata"/>
+
+ <!-- area -->
+
+ <ref-rename name="db.area.inareaset" rename="db.area"/>
+
+ <!-- group -->
+
+ <ref-rename name="db.group.methodparam" rename="db.group"/>
+ <ref-rename name="db.group.paramdef" rename="db.group"/>
+
+ <!-- info -->
+
+ <ref-rename name="db.titlereq.info" rename="db.info"/>
+ <ref-rename name="db.titleonly.info" rename="db.info"/>
+ <ref-rename name="db.titleonlyreq.info" rename="db.info"/>
+ <ref-rename name="db.titleforbidden.info" rename="db.info"/>
+
+ <!-- tables -->
+
+ <ref-rename name="db.html.thead" rename="db.thead"/>
+ <ref-rename name="db.cals.thead" rename="db.thead"/>
+ <ref-rename name="db.html.tfoot" rename="db.tfoot"/>
+ <ref-rename name="db.cals.tfoot" rename="db.tfoot"/>
+ <ref-rename name="db.cals.tbody" rename="db.tbody"/>
+ <ref-rename name="db.html.tbody" rename="db.tbody"/>
+ <ref-rename name="db.entrytbl.row" rename="db.row"/>
+ <ref-rename name="db.html.table" rename="db.table"/>
+ <ref-rename name="db.cals.table" rename="db.table"/>
+ <ref-rename name="db.html.informaltable" rename="db.informaltable"/>
+ <ref-rename name="db.cals.informaltable" rename="db.informaltable"/>
+
+ <ref-rename name="db.cals.entrytbl.thead" rename="db.thead"/>
+ <ref-rename name="db.cals.entrytbl.tbody" rename="db.tbody"/>
+
+</dtd>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<dtd xmlns="http://nwalsh.com/ns/dtd-xml">
+
+ <!-- Fix "any" content -->
+
+ <del-pe name="db._any.attribute"/>
+ <del-element name="db._any"/>
+
+ <!-- Fix indexterm -->
+
+ <ref-rename name="db.indexterm.singular" rename="db.indexterm"/>
+
+ <!-- Fix caption -->
+
+ <ref-rename name="db.html.caption" rename="db.caption"/>
+
+ <!-- Fix limited content model inlines -->
+
+ <del-element name="db._foreignphrase"/>
+ <ref-rename name="db._foreignphrase" rename="db.foreignphrase"/>
+
+ <del-element name="db._emphasis"/>
+ <ref-rename name="db._emphasis" rename="db.emphasis"/>
+
+ <del-element name="db._quote"/>
+ <ref-rename name="db._quote" rename="db.quote"/>
+
+ <del-element name="db._firstterm"/>
+ <ref-rename name="db._firstterm" rename="db.firstterm"/>
+
+ <del-element name="db._glossterm"/>
+ <ref-rename name="db._glossterm" rename="db.glossterm"/>
+
+ <del-element name="db._phrase"/>
+ <ref-rename name="db._phrase" rename="db.phrase"/>
+
+ <!-- Fix SVG and MathML -->
+
+ <ref-rename name="db.imagedata.mathml" rename="db.imagedata"/>
+ <ref-rename name="db.imagedata.svg" rename="db.imagedata"/>
+
+ <!-- area -->
+
+ <ref-rename name="db.area.inareaset" rename="db.area"/>
+
+ <!-- group -->
+
+ <ref-rename name="db.group.methodparam" rename="db.group"/>
+ <ref-rename name="db.group.paramdef" rename="db.group"/>
+
+ <!-- info -->
+
+ <ref-rename name="db.titlereq.info" rename="db.info"/>
+ <ref-rename name="db.titleonly.info" rename="db.info"/>
+ <ref-rename name="db.titleonlyreq.info" rename="db.info"/>
+ <ref-rename name="db.titleforbidden.info" rename="db.info"/>
+
+ <!-- tables -->
+<!--
+ <ref-rename name="db.cals.entrytbl.thead" rename="db.thead"/>
+ <ref-rename name="db.cals.entrytbl.tbody" rename="db.tbody"/>
+-->
+</dtd>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:s="http://www.ascc.net/xml/schematron"
+ xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+ xmlns:dtx="http://nwalsh.com/ns/dtd-xml"
+ xmlns:f="http://nwalsh.com/functions/dtd-xml"
+ xmlns="http://nwalsh.com/ns/dtd-xml"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="s a dtx xs f"
+ version="2.0">
+
+<!-- move the optionality of attributes back up into the declarations -->
+
+<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/>
+
+<xsl:key name="ref" match="dtx:ref|dtx:attref" use="@name"/>
+<xsl:key name="pe" match="dtx:pe" use="@name"/>
+
+<xsl:strip-space elements="*"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="dtx:pe[dtx:attdecl and count(*) = 1]">
+ <xsl:variable name="refs" select="key('ref', @name)"/>
+
+ <xsl:choose>
+ <xsl:when test="count($refs[@optional = 'true']) != count($refs)
+ and count($refs[@optional = 'true']) != 0">
+<!--
+ <xsl:message>Splitting <xsl:value-of select="@name"/></xsl:message>
+-->
+
+ <pe name="{@name}.REQ">
+ <attdecl>
+ <xsl:copy-of select="dtx:attdecl/@*[local-name(.) != 'optional']"/>
+ <xsl:apply-templates select="dtx:attdecl/*"/>
+ </attdecl>
+ </pe>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="dtx:attref[not(@optional='true')]">
+ <xsl:variable name="refs" select="key('ref', @name)"/>
+ <xsl:variable name="target" select="key('pe', @name)"/>
+
+ <!-- The and $target/dtx:attdecl test avoids a bug where db.html.attributes
+ appears sometimes required and sometimes optional but really doesn't
+ matter -->
+
+ <xsl:choose>
+ <xsl:when test="count($refs[@optional = 'true']) != count($refs)
+ and count($refs[@optional = 'true']) != 0
+ and $target/dtx:attdecl">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:attribute name="name" select="concat(@name,'.REQ')"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="dtx:attref[@optional='true']">
+ <xsl:copy>
+ <xsl:copy-of select="@*[local-name(.) != 'optional']"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="dtx:attdecl">
+ <xsl:variable name="pe" select="ancestor::dtx:pe"/>
+ <xsl:variable name="refs" select="key('ref', $pe/@name)"/>
+
+ <xsl:if test="not($pe)">
+ <xsl:message terminate="yes">
+ <xsl:text>dtx:attdecl not an ancestor of a dtx:pe?</xsl:text>
+ </xsl:message>
+ </xsl:if>
+
+<!--
+ <xsl:if test="count($refs[@optional = 'true']) != count($refs)
+ and count($refs[@optional = 'true']) != 0">
+ <xsl:message>
+ <xsl:text>Attribute </xsl:text>
+ <xsl:value-of select="@name"/>
+ <xsl:text> (on </xsl:text>
+ <xsl:value-of select="$pe/@name"/>
+ <xsl:text>) is sometimes optional and sometimes not?</xsl:text>
+ </xsl:message>
+ <xsl:for-each select="$refs">
+ <xsl:message>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@name"/>
+ <xsl:text>: </xsl:text>
+ <xsl:value-of select="@optional"/>
+ </xsl:message>
+ </xsl:for-each>
+ </xsl:if>
+-->
+
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:if test="$refs[@optional = 'true']">
+ <xsl:attribute name="optional" select="'true'"/>
+ </xsl:if>
+ <xsl:apply-templates/>
+ </xsl:copy>
+</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:s="http://www.ascc.net/xml/schematron"
+ xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+ xmlns:dtx="http://nwalsh.com/ns/dtd-xml"
+ xmlns:f="http://nwalsh.com/functions/dtd-xml"
+ xmlns="http://nwalsh.com/ns/dtd-xml"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="s a dtx xs f"
+ version="2.0">
+
+<xsl:include href="common.xsl"/>
+
+<!-- Normalize optionality of attributes: move to ref -->
+
+<xsl:key name="name" match="dtx:pe|dtx:element" use="@name"/>
+
+<xsl:template match="dtx:optional[parent::dtx:pe and dtx:attdecl]">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="dtx:ref">
+ <xsl:variable name="target" select="key('name',@name)"/>
+
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+
+ <xsl:if test="$target[dtx:optional/dtx:attdecl]">
+ <xsl:attribute name="optional" select="'true'"/>
+ </xsl:if>
+
+ <xsl:apply-templates/>
+ </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:s="http://www.ascc.net/xml/schematron"
+ xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+ xmlns:dtx="http://nwalsh.com/ns/dtd-xml"
+ xmlns:f="http://nwalsh.com/functions/dtd-xml"
+ xmlns="http://nwalsh.com/ns/dtd-xml"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="s a dtx xs f"
+ version="2.0">
+
+<xsl:import href="common.xsl"/>
+
+<!-- You can't have a choice of attributes, remove the choice wrapper -->
+
+<xsl:key name="name" match="dtx:pe|dtx:element" use="@name"/>
+
+<xsl:template match="dtx:choice">
+ <xsl:variable name="refs" select="dtx:ref"/>
+ <xsl:variable name="attdecls" select="dtx:attdecl"/>
+ <xsl:variable name="attref" select="f:only-attributes(dtx:ref)"/>
+
+ <xsl:choose>
+ <xsl:when test="count($refs) + count($attdecls) = count(*)">
+ <xsl:choose>
+ <xsl:when test="$attref">
+ <xsl:apply-templates/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="dtx:optional[dtx:ref and count(dtx:ref) = count(*)]">
+ <xsl:variable name="attref" select="f:only-attributes(dtx:ref)"/>
+
+ <xsl:choose>
+ <xsl:when test="$attref">
+ <xsl:for-each select="*">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:attribute name="optional" select="'true'"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <choice>
+ <xsl:apply-templates/>
+ </choice>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="dtx:optional[dtx:attdecl and count(*) = 1]">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<!--
+<xsl:template match="dtx:optional[dtx:attdecl and count(dtx:attdecl) = count(*)]">
+ <xsl:apply-templates/>
+</xsl:template>
+-->
+
+<xsl:template match="dtx:attdecl[ancestor::dtx:optional]">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:attribute name="optional" select="'true'"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="dtx:ref[ancestor::dtx:optional]">
+ <xsl:variable name="target" select="key('name',@name)"/>
+
+ <xsl:choose>
+ <xsl:when test="$target/dtx:attdecl">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:attribute name="optional" select="'true'"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</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:s="http://www.ascc.net/xml/schematron"
+ xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+ xmlns:dtx="http://nwalsh.com/ns/dtd-xml"
+ xmlns:f="http://nwalsh.com/functions/dtd-xml"
+ xmlns="http://nwalsh.com/ns/dtd-xml"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="s a dtx xs f"
+ version="2.0">
+
+<xsl:include href="common.xsl"/>
+
+<!-- Remove dtx:pe elements that are unreferenced -->
+
+<xsl:key name="ref" match="dtx:ref" use="@name"/>
+
+<xsl:template match="dtx:pe">
+ <xsl:variable name="refs" select="key('ref', @name)"/>
+
+ <xsl:if test="$refs">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:if>
+</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:s="http://www.ascc.net/xml/schematron"
+ xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+ xmlns:dtx="http://nwalsh.com/ns/dtd-xml"
+ xmlns:f="http://nwalsh.com/functions/dtd-xml"
+ xmlns="http://nwalsh.com/ns/dtd-xml"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="s a dtx xs f"
+ version="2.0">
+
+<!-- Common declarations -->
+
+<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/>
+
+<xsl:strip-space elements="*"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates/>
+</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>
+
+<!-- Common functions -->
+
+<!-- ============================================================ -->
+
+<xsl:function name="f:only-attributes" as="xs:boolean">
+ <xsl:param name="elem" as="element(dtx:ref)*"/>
+
+<!--
+ <xsl:message>
+ <xsl:value-of select="count($elem)"/>
+ <xsl:text> </xsl:text>
+ <xsl:for-each select="$elem">
+ <xsl:value-of select="@name"/>
+ <xsl:text> </xsl:text>
+ </xsl:for-each>
+ </xsl:message>
+-->
+
+ <xsl:variable name="allatts" as="xs:string*">
+ <xsl:for-each select="$elem">
+ <xsl:variable name="target" select="key('name',@name)"/>
+ <xsl:choose>
+ <xsl:when test="$target/dtx:attdecl">
+ <xsl:text>YES</xsl:text>
+ </xsl:when>
+ <xsl:when test="$target/dtx:ref
+ and count($target/dtx:ref) = count($target/*)">
+ <xsl:choose>
+ <xsl:when test="f:only-attributes($target/dtx:ref)">YES</xsl:when>
+ <xsl:otherwise>NO</xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="$target/dtx:choice and count($target/*) = 1
+ and $target/dtx:choice/dtx:ref
+ and count($target/dtx:choice/dtx:ref)
+ = count($target/dtx:choice/*)">
+ <xsl:choose>
+ <xsl:when test="f:only-attributes($target/dtx:choice/dtx:ref)">YES</xsl:when>
+ <xsl:otherwise>NO</xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>NO</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:variable>
+
+ <xsl:value-of select="not($allatts = 'NO')"/>
+</xsl:function>
+
+</xsl:stylesheet>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:s="http://www.ascc.net/xml/schematron"
+ xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+ xmlns:dtx="http://nwalsh.com/ns/dtd-xml"
+ xmlns:f="http://nwalsh.com/functions/dtd-xml"
+ xmlns="http://nwalsh.com/ns/dtd-xml"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="s a dtx xs f"
+ version="2.0">
+
+<!-- If the contents of an attdecl is a ref, inline the referenced content -->
+
+<xsl:param name="prefix" select="''"/>
+<xsl:param name="ns" select="'http://docbook.org/ns/docbook'"/>
+
+<xsl:output method="text" encoding="utf-8"/>
+
+<xsl:key name="name" match="dtx:pe|dtx:element" use="@name"/>
+
+<xsl:strip-space elements="*"/>
+
+<xsl:template match="/">
+ <!-- This is silly, but we do it for XProc -->
+ <dtd>
+ <xsl:apply-templates/>
+ </dtd>
+</xsl:template>
+
+<xsl:template match="dtx:dtd">
+ <xsl:apply-templates select="dtx:pe">
+ <xsl:sort select="@depth"/>
+ </xsl:apply-templates>
+ <xsl:apply-templates select="*[not(self::dtx:pe)]"/>
+</xsl:template>
+
+<xsl:template match="dtx:pe">
+ <xsl:text> <!ENTITY % </xsl:text>
+ <xsl:value-of select="@name"/>
+ <xsl:text> 	"</xsl:text>
+
+ <xsl:choose>
+ <xsl:when test="dtx:attref|dtx:attdecl">
+ <xsl:apply-templates/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="implicit-group"/>
+ </xsl:otherwise>
+ </xsl:choose>
+<!--
+ <xsl:choose>
+ <xsl:when test="count(dtx:ref) > 1">
+ <xsl:for-each select="dtx:ref">
+ <xsl:if test="position() > 1"> | </xsl:if>
+ <xsl:apply-templates select="."/>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates/>
+ </xsl:otherwise>
+ </xsl:choose>
+-->
+
+ <xsl:text>" > </xsl:text>
+</xsl:template>
+
+<xsl:template match="dtx:element">
+ <xsl:text> <!ATTLIST </xsl:text>
+ <xsl:value-of select="if ($prefix) then concat($prefix, ':') else ''"/>
+ <xsl:value-of select="@gi"/>
+ <xsl:text> 	</xsl:text>
+
+ <xsl:text>xmlns</xsl:text>
+ <xsl:value-of select="if ($prefix) then concat(':', $prefix) else ''"/>
+ <xsl:text>	CDATA	#FIXED "</xsl:text>
+ <xsl:value-of select="$ns"/>
+ <xsl:text>" 	</xsl:text>
+
+ <xsl:text>xmlns:xlink</xsl:text>
+ <xsl:text>	CDATA	#FIXED "http://www.w3.org/1999/xlink"</xsl:text>
+ <xsl:text> 	</xsl:text>
+
+ <xsl:apply-templates select="dtx:attref"/>
+
+ <xsl:text> > </xsl:text>
+
+ <xsl:text> <!ELEMENT </xsl:text>
+ <xsl:value-of select="if ($prefix) then concat($prefix, ':') else ''"/>
+ <xsl:value-of select="@gi"/>
+ <xsl:text> 	</xsl:text>
+
+ <xsl:variable name="cm" select="*[not(self::dtx:attref)]"/>
+
+ <xsl:choose>
+ <xsl:when test="count($cm) = 1 and $cm[1]/self::dtx:text">
+ <xsl:text>(#PCDATA)*</xsl:text>
+ </xsl:when>
+ <xsl:when test=".//dtx:text">
+ <xsl:call-template name="mixed-content">
+ <xsl:with-param name="cm" select="$cm"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="count($cm) > 1">
+ <xsl:text>(</xsl:text>
+ <xsl:for-each select="$cm">
+ <xsl:if test="position() > 1">, </xsl:if>
+ <xsl:apply-templates select="."/>
+ </xsl:for-each>
+ <xsl:text>)</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>(</xsl:text>
+ <xsl:apply-templates select="$cm"/>
+ <xsl:text>)</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:text> > </xsl:text>
+</xsl:template>
+
+<xsl:template match="dtx:attdecl">
+ <xsl:value-of select="@name"/>
+ <xsl:text>	</xsl:text>
+
+ <xsl:choose>
+ <xsl:when test="not(*)">CDATA</xsl:when>
+ <xsl:when test="dtx:data">
+ <xsl:apply-templates select="dtx:data"/>
+ </xsl:when>
+ <xsl:when test="dtx:value">
+ <xsl:text>(</xsl:text>
+ <xsl:for-each select="dtx:value">
+ <xsl:if test="position()>1">|</xsl:if>
+ <xsl:value-of select="."/>
+ </xsl:for-each>
+ <xsl:text>)</xsl:text>
+ </xsl:when>
+ <xsl:when test="dtx:choice">
+ <xsl:apply-templates select="."/>
+ </xsl:when>
+ <xsl:when test="dtx:ref">
+ <xsl:text>%</xsl:text>
+ <xsl:value-of select="dtx:ref/@name"/>
+ <xsl:text>;</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:message>Unknown attribute type: <xsl:copy-of select="*"/></xsl:message>
+ <xsl:text>???</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:text>	</xsl:text>
+ <xsl:choose>
+ <xsl:when test="@optional = 'true' or @name = 'xlink:href'">
+ <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="dtx:ref">
+ <xsl:variable name="target" select="key('name', @name)"/>
+
+ <xsl:choose>
+ <xsl:when test="$target/self::dtx:pe">
+ <xsl:choose>
+ <xsl:when test="@optional = 'true'">
+ <xsl:text>(%</xsl:text>
+ <xsl:value-of select="@name"/>
+ <xsl:text>;)?</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>%</xsl:text>
+ <xsl:value-of select="@name"/>
+ <xsl:text>;</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="$target/self::dtx:element">
+ <xsl:value-of select="if ($prefix) then concat($prefix, ':') else ''"/>
+ <xsl:value-of select="$target/@gi"/>
+ <xsl:if test="@optional = 'true'">?</xsl:if>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:message>
+ <xsl:text>dtx:ref points to neither pe nor element? </xsl:text>
+ <xsl:value-of select="@name"/>
+ </xsl:message>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="dtx:attref">
+ <xsl:text>%</xsl:text>
+ <xsl:value-of select="@name"/>
+ <xsl:text>; 	</xsl:text>
+</xsl:template>
+
+<xsl:template match="dtx:text">#PCDATA</xsl:template>
+
+<xsl:template match="dtx:empty">EMPTY</xsl:template>
+
+<xsl:template match="dtx:optional">
+ <xsl:call-template name="implicit-group"/>
+ <xsl:text>?</xsl:text>
+</xsl:template>
+
+<xsl:template match="dtx:value">
+ <xsl:value-of select="."/>
+</xsl:template>
+
+<xsl:template match="dtx:data">
+ <xsl:choose>
+ <xsl:when test="@type='IDREF' or @type='IDREFS' or @type='ID'
+ or @type='ENTITY' or @type='NMTOKEN'">
+ <xsl:value-of select="@type"/>
+ </xsl:when>
+ <xsl:when test="@type='anyURI' or @type='token'
+ or @type='decimal' or @type='integer'
+ or @type='positiveInteger'
+ or @type='nonNegativeInteger'
+ or @type='date' or @type='dateTime'
+ or @type='gYearMonth' or @type='gYear'">
+ <xsl:text>CDATA</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:message>DATA: <xsl:copy-of select="."/></xsl:message>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="dtx:choice|dtx:zeroOrMore|dtx:oneOrMore">
+ <xsl:text>(</xsl:text>
+ <xsl:for-each select="*">
+ <xsl:if test="position() > 1"> | </xsl:if>
+ <xsl:apply-templates select="."/>
+ </xsl:for-each>
+ <xsl:text>)</xsl:text>
+ <xsl:if test="self::dtx:zeroOrMore">*</xsl:if>
+ <xsl:if test="self::dtx:oneOrMore">+</xsl:if>
+</xsl:template>
+
+<xsl:template match="dtx:group">
+ <xsl:text>(</xsl:text>
+ <xsl:for-each select="*">
+ <xsl:if test="position() > 1">, </xsl:if>
+ <xsl:apply-templates select="."/>
+ </xsl:for-each>
+ <xsl:text>)</xsl:text>
+</xsl:template>
+
+<xsl:template match="*">
+ <xsl:message>Unhandled: <xsl:value-of select="local-name(.)"/>
+ </xsl:message>
+</xsl:template>
+
+<xsl:template match="comment()|processing-instruction()|text()">
+ <xsl:copy/>
+</xsl:template>
+
+<xsl:template name="implicit-group">
+ <xsl:choose>
+ <xsl:when test="count(*) > 1">
+ <xsl:text>(</xsl:text>
+ <xsl:for-each select="*">
+ <xsl:if test="position() > 1">, </xsl:if>
+ <xsl:apply-templates select="."/>
+ </xsl:for-each>
+ <xsl:text>)</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<!-- ============================================================ -->
+
+<xsl:template name="mixed-content">
+ <xsl:param name="cm"/>
+
+<!--
+ <xsl:variable name="refs" as="xs:string*">
+ <xsl:apply-templates select="$cm" mode="mixed-refs"/>
+ </xsl:variable>
+
+ <xsl:message>element: <xsl:value-of select="@gi"/></xsl:message>
+ <xsl:message><xsl:value-of select="distinct-values($refs)"/></xsl:message>
+
+ <xsl:call-template name="collapse-mixed">
+ <xsl:with-param name="refs" select="distinct-values($refs)"/>
+ </xsl:call-template>
+-->
+
+ <xsl:variable name="gis" as="xs:string*">
+ <xsl:apply-templates select="$cm" mode="mixed"/>
+ </xsl:variable>
+
+ <xsl:text>(#PCDATA</xsl:text>
+ <xsl:for-each select="distinct-values($gis)">
+ <xsl:sort select="."/>
+ <xsl:if test=". != '#PCDATA'">
+ <xsl:text> | </xsl:text>
+ <xsl:value-of select="if ($prefix) then concat($prefix, ':') else ''"/>
+ <xsl:value-of select="."/>
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:text>)*</xsl:text>
+</xsl:template>
+
+<xsl:template match="dtx:text" mode="mixed">
+ <xsl:text>#PCDATA</xsl:text>
+</xsl:template>
+
+<xsl:template match="dtx:ref" mode="mixed">
+ <xsl:variable name="target" select="key('name', @name)"/>
+
+ <xsl:choose>
+ <xsl:when test="$target/self::dtx:element">
+ <xsl:value-of select="concat(if ($prefix) then concat($prefix, ':') else '',
+ $target/@gi)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="$target/*" mode="mixed"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="dtx:choice|dtx:zeroOrMore|dtx:oneOrMore|dtx:optional"
+ mode="mixed">
+ <xsl:apply-templates mode="mixed"/>
+</xsl:template>
+
+<!-- ============================================================ -->
+
+<xsl:template match="dtx:ref" mode="mixed-refs">
+ <xsl:variable name="target" select="key('name', @name)"/>
+
+ <xsl:choose>
+ <xsl:when test="$target/self::dtx:element">
+ <xsl:value-of select="$target/@gi"/>
+ </xsl:when>
+ <xsl:when test="$target/self::dtx:pe and f:ref-bottom($target)">
+ <xsl:value-of select="@name"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="$target/*" mode="mixed-refs"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="dtx:choice|dtx:zeroOrMore|dtx:oneOrMore|dtx:optional"
+ mode="mixed-refs">
+ <xsl:apply-templates mode="mixed-refs"/>
+</xsl:template>
+
+<xsl:template match="dtx:text"
+ mode="mixed-refs"/>
+
+<xsl:template match="*"
+ mode="mixed-refs">
+ <xsl:message>Not handled in mixed-refs mode: <xsl:value-of select="local-name(.)"/></xsl:message>
+</xsl:template>
+
+<xsl:template match="comment()|processing-instruction()|text()" mode="mixed-refs"/>
+
+<!-- ============================================================ -->
+
+<xsl:function name="f:ref-bottom" as="xs:boolean">
+ <xsl:param name="elem" as="element(dtx:pe)"/>
+
+ <xsl:variable name="allatts" as="xs:string*">
+ <xsl:for-each select="$elem//dtx:ref">
+ <xsl:variable name="target" select="key('name',@name)"/>
+ <xsl:choose>
+ <xsl:when test="$target/self::dtx:element">YES</xsl:when>
+ <xsl:when test="$target/self::dtx:pe">NO</xsl:when>
+ <xsl:otherwise>
+ <xsl:message>
+ <xsl:text>Unexpected ref: </xsl:text>
+ <xsl:value-of select="local-name($target)"/>
+ </xsl:message>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:variable>
+
+ <xsl:value-of select="not($allatts = 'NO')"/>
+</xsl:function>
+
+<!-- ============================================================ -->
+
+<xsl:template name="collapse-mixed">
+ <xsl:param name="refs" as="xs:string*"/>
+ <xsl:param name="elements" as="xs:string*" select="()"/>
+ <xsl:param name="pes" as="xs:string*" select="()"/>
+
+ <xsl:variable name="allelem" as="xs:string*">
+ <xsl:for-each select="$elements"><xsl:value-of select="."/></xsl:for-each>
+ <xsl:for-each select="$refs">
+ <xsl:variable name="target" select="key('name', .)"/>
+ <xsl:if test="$target/self::dtx:element">
+ <xsl:value-of select="."/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+
+<!--
+ <xsl:variable name="newelem" select="distinct-values($allelem)"/>
+
+ <xsl:variable name="newpes" as="xs:string*">
+ <xsl:for-each select="$refs">
+ <xsl:if test="not(. = $newelem)">
+ <xsl:value-of select="."/>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:variable>
+
+ <xsl:message>ELEM: <xsl:value-of select="$newelem"/></xsl:message>
+ <xsl:message>PES: <xsl:value-of select="$newpes"/></xsl:message>
+-->
+
+ <xsl:value-of select="''"/>
+
+</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:s="http://www.ascc.net/xml/schematron"
+ xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+ xmlns:dtx="http://nwalsh.com/ns/dtd-xml"
+ xmlns:f="http://nwalsh.com/functions/dtd-xml"
+ xmlns="http://nwalsh.com/ns/dtd-xml"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="s a dtx xs f"
+ version="2.0">
+
+<xsl:import href="common.xsl"/>
+
+<!-- Flatten chains of attrefs -->
+
+<xsl:key name="name" match="dtx:pe" use="@name"/>
+<xsl:key name="use" match="dtx:ref|dtx:attref" use="@name"/>
+
+<xsl:template match="dtx:pe">
+ <xsl:choose>
+ <xsl:when test="key('use',@name)">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:otherwise>
+<!--
+ <xsl:message>Unused pattern: <xsl:value-of select="@name"/></xsl:message>
+-->
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="dtx:attref">
+ <xsl:variable name="target" select="key('name',@name)"/>
+
+ <xsl:choose>
+ <xsl:when test="$target/dtx:attref and count($target/dtx:attref) = 1">
+<!--
+ <xsl:message>
+ <xsl:value-of select="@name"/>
+ <xsl:text> is just another name for </xsl:text>
+ <xsl:value-of select="$target/dtx:attref/@name"/>
+ </xsl:message>
+-->
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:attribute name="name" select="$target/dtx:attref/@name"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</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:s="http://www.ascc.net/xml/schematron"
+ xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+ xmlns:dtx="http://nwalsh.com/ns/dtd-xml"
+ xmlns:f="http://nwalsh.com/functions/dtd-xml"
+ xmlns="http://nwalsh.com/ns/dtd-xml"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="s a dtx xs f"
+ version="2.0">
+
+<xsl:include href="common.xsl"/>
+
+<!-- Detect multiple platterns that define the same GI -->
+
+<xsl:key name="gi" match="dtx:element" use="@gi"/>
+
+<xsl:template match="dtx:element[@gi]">
+ <xsl:variable name="gi" select="@gi"/>
+ <xsl:variable name="gis" select="key('gi', @gi)"/>
+
+ <xsl:choose>
+ <xsl:when test="count($gis) = 1">
+ <xsl:next-match/>
+ </xsl:when>
+ <xsl:when test="preceding-sibling::dtx:element[@gi = $gi]">
+ <xsl:next-match/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:message>Duplicate patterns for <xsl:value-of select="$gi"/></xsl:message>
+ <xsl:next-match/>
+ </xsl:otherwise>
+ </xsl:choose>
+</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"
+ xmlns:s="http://www.ascc.net/xml/schematron"
+ xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+ xmlns:dtx="http://nwalsh.com/ns/dtd-xml"
+ xmlns="http://nwalsh.com/ns/dtd-xml"
+ exclude-result-prefixes="rng s a dtx"
+ version="2.0">
+
+<xsl:include href="common.xsl"/>
+
+<!-- apply the rules in the specified overrride file -->
+
+<xsl:param name="override.xml" required="yes"/>
+
+<xsl:variable name="overrides" select="doc($override.xml)/dtx:dtd"/>
+
+<xsl:key name="name" match="dtx:pe|dtx:element" use="@name"/>
+
+<xsl:template match="dtx:pe">
+ <xsl:variable name="name" select="@name"/>
+
+ <xsl:choose>
+ <xsl:when test="$overrides/dtx:del-pe[@name = $name]"/>
+ <xsl:when test="$overrides/dtx:pe[@name = $name]">
+ <xsl:variable name="pe" select="$overrides/dtx:pe[@name = $name]"/>
+ <xsl:if test="$pe/*">
+ <xsl:copy-of select="$pe"/>
+ </xsl:if>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="dtx:element">
+ <xsl:variable name="name" select="@name"/>
+
+ <xsl:choose>
+ <xsl:when test="$overrides/dtx:del-element[@name = $name]"/>
+ <xsl:when test="$overrides/dtx:element[@name = $name]">
+ <xsl:sequence select="$overrides/dtx:element[@name = $name]"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="dtx:ref">
+ <xsl:variable name="name" select="@name"/>
+
+ <xsl:choose>
+ <xsl:when test="$overrides/dtx:del-ref[@name = $name]"/>
+ <xsl:when test="$overrides/dtx:ref-rename[@name = $name]">
+ <xsl:variable name="rename" select="$overrides/dtx:ref-rename[@name = $name]"/>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:attribute name="name" select="$rename/@rename"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</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:s="http://www.ascc.net/xml/schematron"
+ xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+ xmlns:dtx="http://nwalsh.com/ns/dtd-xml"
+ xmlns:f="http://nwalsh.com/functions/dtd-xml"
+ xmlns="http://nwalsh.com/ns/dtd-xml"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="s a dtx xs f"
+ version="2.0">
+
+<xsl:include href="common.xsl"/>
+
+<!-- replace a ref to a pe that contains text with the content of the pe -->
+
+<xsl:key name="pe" match="dtx:pe" use="@name"/>
+
+<xsl:template match="dtx:ref">
+ <xsl:variable name="target" select="key('pe', @name)"/>
+
+ <xsl:choose>
+ <xsl:when test="$target//dtx:text">
+ <xsl:copy-of select="$target/*"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:next-match/>
+ </xsl:otherwise>
+ </xsl:choose>
+</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:s="http://www.ascc.net/xml/schematron"
+ xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+ xmlns:dtx="http://nwalsh.com/ns/dtd-xml"
+ xmlns:f="http://nwalsh.com/functions/dtd-xml"
+ xmlns="http://nwalsh.com/ns/dtd-xml"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="s a dtx xs f"
+ version="2.0">
+
+<xsl:include href="common.xsl"/>
+
+<!-- Change ref's that point exclusively to attributes into attref's -->
+
+<xsl:key name="name" match="dtx:pe|dtx:element" use="@name"/>
+
+<xsl:template match="dtx:ref">
+ <xsl:variable name="attref" select="f:only-attributes(.)"/>
+
+ <xsl:choose>
+ <xsl:when test="$attref">
+ <attref>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </attref>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</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:s="http://www.ascc.net/xml/schematron"
+ xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+ xmlns:dtx="http://nwalsh.com/ns/dtd-xml"
+ xmlns:f="http://nwalsh.com/functions/dtd-xml"
+ xmlns="http://nwalsh.com/ns/dtd-xml"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="s a dtx xs f"
+ version="2.0">
+
+<!-- If a pe is empty, remove it and references to it -->
+
+<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/>
+
+<xsl:key name="pe" match="dtx:pe" use="@name"/>
+
+<xsl:strip-space elements="*"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="dtx:pe[not(*)]">
+ <!-- nop -->
+ <!--
+ <xsl:message>Remove empty PE: <xsl:value-of select="@name"/></xsl:message>
+ -->
+</xsl:template>
+
+<xsl:template match="dtx:ref">
+ <xsl:variable name="target" select="key('pe', @name)"/>
+
+ <xsl:choose>
+ <xsl:when test="$target and not($target/*)">
+ <!-- nop -->
+ <!--
+ <xsl:message>Remove ref to PE: <xsl:value-of select="@name"/></xsl:message>
+ -->
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:next-match/>
+ </xsl:otherwise>
+ </xsl:choose>
+</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:rng="http://relaxng.org/ns/structure/1.0"
+ xmlns:s="http://www.ascc.net/xml/schematron"
+ xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+ xmlns:dtx="http://nwalsh.com/ns/dtd-xml"
+ xmlns="http://nwalsh.com/ns/dtd-xml"
+ exclude-result-prefixes="rng s a dtx"
+ version="2.0">
+
+<xsl:include href="common.xsl"/>
+
+<!-- Rough conversion of rng:* to dtx:* -->
+
+<xsl:template match="rng:grammar">
+ <dtd>
+ <xsl:apply-templates/>
+ </dtd>
+</xsl:template>
+
+<xsl:template match="s:ns"/>
+<xsl:template match="s:pattern"/>
+<xsl:template match="rng:start"/>
+<xsl:template match="a:documentation"/>
+
+<xsl:template match="rng:div">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="rng:interleave">
+ <choice>
+ <xsl:apply-templates/>
+ </choice>
+</xsl:template>
+
+<xsl:template match="rng:optional[rng:ref and count(*) = 1]">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="rng:choice[parent::rng:choice]">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="rng:choice|rng:zeroOrMore|rng:oneOrMore|rng:optional
+ |rng:empty|rng:text|rng:group|rng:value|rng:data">
+ <xsl:element name="{local-name(.)}" namespace="http://nwalsh.com/ns/dtd-xml">
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:element>
+</xsl:template>
+
+<xsl:template match="rng:define[@name='db._any']" priority="500">
+ <element name="db._any"/>
+</xsl:template>
+
+<xsl:template match="rng:define[rng:element and count(*) = 1]">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="rng:define">
+ <pe name="{@name}">
+ <xsl:apply-templates/>
+ </pe>
+</xsl:template>
+
+<xsl:template match="rng:attribute">
+ <attdecl name="{@name}">
+ <xsl:apply-templates select="rng:value|rng:data|rng:ref"/>
+ </attdecl>
+</xsl:template>
+
+<xsl:template match="rng:element">
+ <element name="{../@name}">
+ <xsl:if test="@name">
+ <xsl:attribute name="gi" select="@name"/>
+ </xsl:if>
+ <xsl:apply-templates/>
+ </element>
+</xsl:template>
+
+<xsl:template match="rng:ref">
+ <ref name="{@name}">
+ <xsl:if test="parent::rng:optional">
+ <xsl:attribute name="optional" select="'true'"/>
+ </xsl:if>
+ </ref>
+</xsl:template>
+
+<xsl:template match="rng:notAllowed">
+ <!-- nop -->
+</xsl:template>
+
+<xsl:template match="rng:param">
+ <!-- nop -->
+</xsl:template>
+
+<xsl:template match="*">
+ <xsl:message>
+ <xsl:text>Failed to handle element: </xsl:text>
+ <xsl:value-of select="node-name(.)"/>
+ </xsl:message>
+</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:s="http://www.ascc.net/xml/schematron"
+ xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+ xmlns:dtx="http://nwalsh.com/ns/dtd-xml"
+ xmlns:f="http://nwalsh.com/functions/dtd-xml"
+ xmlns="http://nwalsh.com/ns/dtd-xml"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="s a dtx xs f"
+ version="2.0">
+
+<!-- Sort the PEs so that they aren't referenced before they're declared -->
+
+<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/>
+
+<xsl:key name="pes" match="dtx:pe" use="@name"/>
+
+<xsl:strip-space elements="*"/>
+
+<xsl:variable name="depth"
+ select="if (//dtx:pe[@depth])
+ then max(//dtx:pe[@depth]/@depth)
+ else 0"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="dtx:pe[not(@depth)]">
+ <xsl:choose>
+ <xsl:when test="$depth = 0">
+ <xsl:choose>
+ <xsl:when test="not(.//dtx:ref) and not(.//dtx:attref)">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:attribute name="depth" select="1"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="depths" as="xs:integer*">
+ <xsl:for-each select=".//dtx:ref|.//dtx:attref">
+ <xsl:variable name="target" select="key('pes',@name)"/>
+ <xsl:choose>
+ <xsl:when test="not($target)"/>
+ <xsl:when test="$target/@depth">
+ <xsl:value-of select="$target/@depth"/>
+ </xsl:when>
+ <xsl:otherwise>0</xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="$depths = 0">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:when test="empty($depths)">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:attribute name="depth" select="1"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:attribute name="depth" select="max($depths)+1"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+</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:s="http://www.ascc.net/xml/schematron"
+ xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+ xmlns:dtx="http://nwalsh.com/ns/dtd-xml"
+ xmlns:f="http://nwalsh.com/functions/dtd-xml"
+ xmlns="http://nwalsh.com/ns/dtd-xml"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="s a dtx xs f"
+ version="2.0">
+
+<xsl:include href="common.xsl"/>
+
+<!-- If a zerorOrMore contains a zeroOrMore, unwrap it -->
+
+<xsl:key name="ref" match="dtx:ref" use="@name"/>
+
+<xsl:template match="dtx:zeroOrMore[parent::dtx:zeroOrMore]">
+ <xsl:apply-templates/>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<!DOCTYPE db:book SYSTEM "../output.dtd">
+<db:book xmlns:db="http://docbook.org/ns/docbook">
+<db:info>
+ <db:title>Book title</db:title>
+</db:info>
+<db:chapter>
+<db:title>Chapter title</db:title>
+<db:para>Some text.</db:para>
+</db:chapter>
+</db:book>
--- /dev/null
+<!DOCTYPE book SYSTEM "../output.dtd">
+<book>
+<info>
+ <title>Book title</title>
+</info>
+<chapter>
+<title>Chapter title</title>
+<para>Some text.</para>
+</chapter>
+</book>