]> granicus.if.org Git - docbook-dsssl/commitdiff
Initial checkin of toolchain for converting DocBook RNG schemas to DTDs and XSDs
authorNorman Walsh <ndw@nwalsh.com>
Fri, 19 Mar 2010 00:16:32 +0000 (00:16 +0000)
committerNorman Walsh <ndw@nwalsh.com>
Fri, 19 Mar 2010 00:16:32 +0000 (00:16 +0000)
21 files changed:
docbook/relaxng/tools/rng2dtd/pipe.xpl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/rng2dtd.xpl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/src/override-docbook.xml [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/src/override-publishers.xml [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/style/attr-optional-to-decl.xsl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/style/attr-optional-to-ref.xsl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/style/attr-remove-choice.xsl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/style/attr-remove-unused.xsl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/style/common.xsl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/style/dtx2dtd.xsl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/style/flatten-attref.xsl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/style/multiple-gis.xsl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/style/override.xsl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/style/pull-up-text.xsl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/style/ref-to-attref.xsl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/style/remove-empty-pes.xsl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/style/rng2dtx.xsl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/style/sort-pes.xsl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/style/unwrap-zeroormore.xsl [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/test/dbdoc.xml [new file with mode: 0644]
docbook/relaxng/tools/rng2dtd/test/doc.xml [new file with mode: 0644]

diff --git a/docbook/relaxng/tools/rng2dtd/pipe.xpl b/docbook/relaxng/tools/rng2dtd/pipe.xpl
new file mode 100644 (file)
index 0000000..adaa8a9
--- /dev/null
@@ -0,0 +1,205 @@
+<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>
diff --git a/docbook/relaxng/tools/rng2dtd/rng2dtd.xpl b/docbook/relaxng/tools/rng2dtd/rng2dtd.xpl
new file mode 100644 (file)
index 0000000..cefbac9
--- /dev/null
@@ -0,0 +1,121 @@
+<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>
diff --git a/docbook/relaxng/tools/rng2dtd/src/override-docbook.xml b/docbook/relaxng/tools/rng2dtd/src/override-docbook.xml
new file mode 100644 (file)
index 0000000..de9f829
--- /dev/null
@@ -0,0 +1,75 @@
+<?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>
diff --git a/docbook/relaxng/tools/rng2dtd/src/override-publishers.xml b/docbook/relaxng/tools/rng2dtd/src/override-publishers.xml
new file mode 100644 (file)
index 0000000..e9b85a4
--- /dev/null
@@ -0,0 +1,63 @@
+<?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>
diff --git a/docbook/relaxng/tools/rng2dtd/style/attr-optional-to-decl.xsl b/docbook/relaxng/tools/rng2dtd/style/attr-optional-to-decl.xsl
new file mode 100644 (file)
index 0000000..6024e49
--- /dev/null
@@ -0,0 +1,140 @@
+<?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>
diff --git a/docbook/relaxng/tools/rng2dtd/style/attr-optional-to-ref.xsl b/docbook/relaxng/tools/rng2dtd/style/attr-optional-to-ref.xsl
new file mode 100644 (file)
index 0000000..0e864b0
--- /dev/null
@@ -0,0 +1,36 @@
+<?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>
diff --git a/docbook/relaxng/tools/rng2dtd/style/attr-remove-choice.xsl b/docbook/relaxng/tools/rng2dtd/style/attr-remove-choice.xsl
new file mode 100644 (file)
index 0000000..0bec730
--- /dev/null
@@ -0,0 +1,105 @@
+<?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>
diff --git a/docbook/relaxng/tools/rng2dtd/style/attr-remove-unused.xsl b/docbook/relaxng/tools/rng2dtd/style/attr-remove-unused.xsl
new file mode 100644 (file)
index 0000000..9382d78
--- /dev/null
@@ -0,0 +1,29 @@
+<?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>
diff --git a/docbook/relaxng/tools/rng2dtd/style/common.xsl b/docbook/relaxng/tools/rng2dtd/style/common.xsl
new file mode 100644 (file)
index 0000000..642e1e6
--- /dev/null
@@ -0,0 +1,84 @@
+<?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>
diff --git a/docbook/relaxng/tools/rng2dtd/style/dtx2dtd.xsl b/docbook/relaxng/tools/rng2dtd/style/dtx2dtd.xsl
new file mode 100644 (file)
index 0000000..d3da388
--- /dev/null
@@ -0,0 +1,431 @@
+<?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>  &lt;!ENTITY % </xsl:text>
+  <xsl:value-of select="@name"/>
+  <xsl:text>&#10;&#9;"</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) &gt; 1">
+      <xsl:for-each select="dtx:ref">
+        <xsl:if test="position() &gt; 1"> | </xsl:if>
+        <xsl:apply-templates select="."/>
+      </xsl:for-each>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:apply-templates/>
+    </xsl:otherwise>
+  </xsl:choose>
+-->
+
+  <xsl:text>"&#10;&gt;&#10;&#10;</xsl:text>
+</xsl:template>
+
+<xsl:template match="dtx:element">
+  <xsl:text>  &lt;!ATTLIST </xsl:text>
+  <xsl:value-of select="if ($prefix) then concat($prefix, ':') else ''"/>
+  <xsl:value-of select="@gi"/>
+  <xsl:text>&#10;&#9;</xsl:text>
+
+  <xsl:text>xmlns</xsl:text>
+  <xsl:value-of select="if ($prefix) then concat(':', $prefix) else ''"/>
+  <xsl:text>&#9;CDATA&#9;#FIXED "</xsl:text>
+  <xsl:value-of select="$ns"/>
+  <xsl:text>"&#10;&#9;</xsl:text>
+
+  <xsl:text>xmlns:xlink</xsl:text>
+  <xsl:text>&#9;CDATA&#9;#FIXED "http://www.w3.org/1999/xlink"</xsl:text>
+  <xsl:text>&#10;&#9;</xsl:text>
+
+  <xsl:apply-templates select="dtx:attref"/>
+
+  <xsl:text>&#10;&gt;&#10;&#10;</xsl:text>
+
+  <xsl:text>  &lt;!ELEMENT </xsl:text>
+  <xsl:value-of select="if ($prefix) then concat($prefix, ':') else ''"/>
+  <xsl:value-of select="@gi"/>
+  <xsl:text>&#10;&#9;</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) &gt; 1">
+      <xsl:text>(</xsl:text>
+      <xsl:for-each select="$cm">
+        <xsl:if test="position() &gt; 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>&#10;&gt;&#10;&#10;</xsl:text>
+</xsl:template>
+
+<xsl:template match="dtx:attdecl">
+  <xsl:value-of select="@name"/>
+  <xsl:text>&#9;</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()&gt;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>&#9;</xsl:text>
+  <xsl:choose>
+    <xsl:when test="@optional = 'true' or @name = 'xlink:href'">
+      <xsl:text>&#9;#IMPLIED</xsl:text>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:text>&#9;#REQUIRED</xsl:text>
+    </xsl:otherwise>
+  </xsl:choose>
+
+  <xsl:text>&#10;&#9;</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>;&#10;&#9;</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() &gt; 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() &gt; 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(*) &gt; 1">
+      <xsl:text>(</xsl:text>
+      <xsl:for-each select="*">
+        <xsl:if test="position() &gt; 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>
diff --git a/docbook/relaxng/tools/rng2dtd/style/flatten-attref.xsl b/docbook/relaxng/tools/rng2dtd/style/flatten-attref.xsl
new file mode 100644 (file)
index 0000000..0c4c0e7
--- /dev/null
@@ -0,0 +1,62 @@
+<?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>
diff --git a/docbook/relaxng/tools/rng2dtd/style/multiple-gis.xsl b/docbook/relaxng/tools/rng2dtd/style/multiple-gis.xsl
new file mode 100644 (file)
index 0000000..8d7d201
--- /dev/null
@@ -0,0 +1,36 @@
+<?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>
diff --git a/docbook/relaxng/tools/rng2dtd/style/override.xsl b/docbook/relaxng/tools/rng2dtd/style/override.xsl
new file mode 100644 (file)
index 0000000..997d682
--- /dev/null
@@ -0,0 +1,80 @@
+<?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>
diff --git a/docbook/relaxng/tools/rng2dtd/style/pull-up-text.xsl b/docbook/relaxng/tools/rng2dtd/style/pull-up-text.xsl
new file mode 100644 (file)
index 0000000..cd652f3
--- /dev/null
@@ -0,0 +1,31 @@
+<?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>
diff --git a/docbook/relaxng/tools/rng2dtd/style/ref-to-attref.xsl b/docbook/relaxng/tools/rng2dtd/style/ref-to-attref.xsl
new file mode 100644 (file)
index 0000000..3048c01
--- /dev/null
@@ -0,0 +1,37 @@
+<?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>
diff --git a/docbook/relaxng/tools/rng2dtd/style/remove-empty-pes.xsl b/docbook/relaxng/tools/rng2dtd/style/remove-empty-pes.xsl
new file mode 100644 (file)
index 0000000..f03fe3a
--- /dev/null
@@ -0,0 +1,58 @@
+<?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>
diff --git a/docbook/relaxng/tools/rng2dtd/style/rng2dtx.xsl b/docbook/relaxng/tools/rng2dtd/style/rng2dtx.xsl
new file mode 100644 (file)
index 0000000..d26e486
--- /dev/null
@@ -0,0 +1,104 @@
+<?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>
diff --git a/docbook/relaxng/tools/rng2dtd/style/sort-pes.xsl b/docbook/relaxng/tools/rng2dtd/style/sort-pes.xsl
new file mode 100644 (file)
index 0000000..7539294
--- /dev/null
@@ -0,0 +1,99 @@
+<?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>
diff --git a/docbook/relaxng/tools/rng2dtd/style/unwrap-zeroormore.xsl b/docbook/relaxng/tools/rng2dtd/style/unwrap-zeroormore.xsl
new file mode 100644 (file)
index 0000000..b5e0580
--- /dev/null
@@ -0,0 +1,22 @@
+<?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>
diff --git a/docbook/relaxng/tools/rng2dtd/test/dbdoc.xml b/docbook/relaxng/tools/rng2dtd/test/dbdoc.xml
new file mode 100644 (file)
index 0000000..85f8592
--- /dev/null
@@ -0,0 +1,10 @@
+<!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>
diff --git a/docbook/relaxng/tools/rng2dtd/test/doc.xml b/docbook/relaxng/tools/rng2dtd/test/doc.xml
new file mode 100644 (file)
index 0000000..aea07a2
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE book SYSTEM "../output.dtd">
+<book>
+<info>
+  <title>Book title</title>
+</info>
+<chapter>
+<title>Chapter title</title>
+<para>Some text.</para>
+</chapter>
+</book>