]> git.0d.be Git - empathy.git/blobdiff - tools/doc-generator.xsl
sort contacts by most recent event
[empathy.git] / tools / doc-generator.xsl
index 83b42dc556039fe1b8ce8c33d4ac131b5a528045..76fc96964a63d101d81846e5c9e6bd3500b199d3 100644 (file)
@@ -2,7 +2,7 @@
 The master copy of this stylesheet is in the Telepathy spec repository -
 please make any changes there.
 
-Copyright (C) 2006, 2007 Collabora Limited
+Copyright (C) 2006-2008 Collabora Limited
 
 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
@@ -12,20 +12,115 @@ version 2.1 of the License, or (at your option) any later version.
 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
+Lesser General Public License for more details.
 
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 -->
 
 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
-  exclude-result-prefixes="tp">
-  <!--Don't move the declaration of the HTML namespace up here - XMLNSs
+  xmlns:html="http://www.w3.org/1999/xhtml"
+  exclude-result-prefixes="tp html">
+  <!--Don't move the declaration of the HTML namespace up here — XMLNSs
   don't work ideally in the presence of two things that want to use the
   absence of a prefix, sadly. -->
 
+  <xsl:param name="allow-undefined-interfaces" select="false()"/>
+
+  <xsl:template match="html:* | @*" mode="html">
+    <xsl:copy>
+      <xsl:apply-templates mode="html"/>
+    </xsl:copy>
+  </xsl:template>
+
+  <xsl:template match="tp:type" mode="html">
+    <xsl:call-template name="tp-type">
+      <xsl:with-param name="tp-type" select="string(.)"/>
+    </xsl:call-template>
+  </xsl:template>
+
+  <!-- tp:dbus-ref: reference a D-Bus interface, signal, method or property -->
+  <xsl:template match="tp:dbus-ref" mode="html">
+    <xsl:variable name="name">
+      <xsl:choose>
+        <xsl:when test="@namespace">
+          <xsl:value-of select="@namespace"/>
+          <xsl:text>.</xsl:text>
+        </xsl:when>
+      </xsl:choose>
+      <xsl:value-of select="string(.)"/>
+    </xsl:variable>
+
+    <xsl:choose>
+      <xsl:when test="//interface[@name=$name]
+        or //interface/method[concat(../@name, '.', @name)=$name]
+        or //interface/signal[concat(../@name, '.', @name)=$name]
+        or //interface/property[concat(../@name, '.', @name)=$name]
+        or //interface[@name=concat($name, '.DRAFT')]
+        or //interface/method[
+          concat(../@name, '.', @name)=concat($name, '.DRAFT')]
+        or //interface/signal[
+          concat(../@name, '.', @name)=concat($name, '.DRAFT')]
+        or //interface/property[
+          concat(../@name, '.', @name)=concat($name, '.DRAFT')]
+        ">
+        <a xmlns="http://www.w3.org/1999/xhtml" href="#{$name}">
+          <xsl:value-of select="string(.)"/>
+        </a>
+      </xsl:when>
+
+      <xsl:when test="$allow-undefined-interfaces">
+        <span xmlns="http://www.w3.org/1999/xhtml" title="defined elsewhere">
+          <xsl:value-of select="string(.)"/>
+        </span>
+      </xsl:when>
+
+      <xsl:otherwise>
+        <xsl:message terminate="yes">
+          <xsl:text>ERR: cannot find D-Bus interface, method, </xsl:text>
+          <xsl:text>signal or property called '</xsl:text>
+          <xsl:value-of select="$name"/>
+          <xsl:text>'&#10;</xsl:text>
+        </xsl:message>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!-- tp:member-ref: reference a property of the current interface -->
+  <xsl:template match="tp:member-ref" mode="html">
+    <xsl:variable name="prefix" select="concat(ancestor::interface/@name,
+      '.')"/>
+    <xsl:variable name="name" select="string(.)"/>
+
+    <xsl:if test="not(ancestor::interface)">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: Cannot use tp:member-ref when not in an</xsl:text>
+        <xsl:text> &lt;interface&gt;&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
+    <xsl:choose>
+      <xsl:when test="ancestor::interface/signal[@name=$name]"/>
+      <xsl:when test="ancestor::interface/method[@name=$name]"/>
+      <xsl:when test="ancestor::interface/property[@name=$name]"/>
+      <xsl:otherwise>
+        <xsl:message terminate="yes">
+          <xsl:text>ERR: interface </xsl:text>
+          <xsl:value-of select="ancestor::interface/@name"/>
+          <xsl:text> has no signal/method/property called </xsl:text>
+          <xsl:value-of select="$name"/>
+          <xsl:text>&#10;</xsl:text>
+        </xsl:message>
+      </xsl:otherwise>
+    </xsl:choose>
+
+    <a xmlns="http://www.w3.org/1999/xhtml" href="#{$prefix}{$name}">
+      <xsl:value-of select="$name"/>
+    </a>
+  </xsl:template>
+
   <xsl:template match="*" mode="identity">
     <xsl:copy>
       <xsl:apply-templates mode="identity"/>
@@ -33,7 +128,39 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   </xsl:template>
 
   <xsl:template match="tp:docstring">
-    <xsl:apply-templates select="node()" mode="identity"/>
+    <xsl:apply-templates mode="html"/>
+  </xsl:template>
+
+  <xsl:template match="tp:added">
+    <p class="added" xmlns="http://www.w3.org/1999/xhtml">Added in
+      version <xsl:value-of select="@version"/>.
+      <xsl:apply-templates select="node()" mode="html"/></p>
+  </xsl:template>
+
+  <xsl:template match="tp:changed">
+    <xsl:choose>
+      <xsl:when test="node()">
+        <p class="changed" xmlns="http://www.w3.org/1999/xhtml">Changed in
+          version <xsl:value-of select="@version"/>:
+          <xsl:apply-templates select="node()" mode="html"/></p>
+      </xsl:when>
+      <xsl:otherwise>
+        <p class="changed">Changed in version
+          <xsl:value-of select="@version"/></p>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="tp:deprecated">
+    <p class="deprecated" xmlns="http://www.w3.org/1999/xhtml">Deprecated
+      since version <xsl:value-of select="@version"/>.
+      <xsl:apply-templates select="node()" mode="html"/></p>
+  </xsl:template>
+
+  <xsl:template match="tp:rationale" mode="html">
+    <div xmlns="http://www.w3.org/1999/xhtml" class="rationale">
+      <xsl:apply-templates select="node()" mode="html"/>
+    </div>
   </xsl:template>
 
   <xsl:template match="tp:errors">
@@ -81,16 +208,19 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   <xsl:template match="tp:error">
     <h2 xmlns="http://www.w3.org/1999/xhtml"><a name="{concat(../@namespace, '.', translate(@name, ' ', ''))}"></a><xsl:value-of select="concat(../@namespace, '.', translate(@name, ' ', ''))"/></h2>
     <xsl:apply-templates select="tp:docstring"/>
+    <xsl:apply-templates select="tp:added"/>
+    <xsl:apply-templates select="tp:changed"/>
+    <xsl:apply-templates select="tp:deprecated"/>
   </xsl:template>
 
   <xsl:template match="/tp:spec/tp:copyright">
     <div xmlns="http://www.w3.org/1999/xhtml">
-      <xsl:apply-templates/>
+      <xsl:apply-templates mode="text"/>
     </div>
   </xsl:template>
   <xsl:template match="/tp:spec/tp:license">
     <div xmlns="http://www.w3.org/1999/xhtml" class="license">
-      <xsl:apply-templates mode="identity"/>
+      <xsl:apply-templates mode="html"/>
     </div>
   </xsl:template>
 
@@ -118,6 +248,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     </xsl:if>
 
     <xsl:apply-templates select="tp:docstring" />
+    <xsl:apply-templates select="tp:added"/>
+    <xsl:apply-templates select="tp:changed"/>
+    <xsl:apply-templates select="tp:deprecated"/>
 
     <xsl:choose>
       <xsl:when test="method">
@@ -141,13 +274,32 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
     <xsl:choose>
       <xsl:when test="tp:property">
-        <h2 xmlns="http://www.w3.org/1999/xhtml">Properties:</h2>
+        <h2 xmlns="http://www.w3.org/1999/xhtml">Telepathy Properties:</h2>
+        <p xmlns="http://www.w3.org/1999/xhtml">Accessed using the
+          <a href="#org.freedesktop.Telepathy.Properties">Telepathy
+            Properties</a> interface.</p>
         <dl xmlns="http://www.w3.org/1999/xhtml">
           <xsl:apply-templates select="tp:property"/>
         </dl>
       </xsl:when>
       <xsl:otherwise>
-        <p xmlns="http://www.w3.org/1999/xhtml">Interface has no properties.</p>
+        <p xmlns="http://www.w3.org/1999/xhtml">Interface has no Telepathy
+          properties.</p>
+      </xsl:otherwise>
+    </xsl:choose>
+
+    <xsl:choose>
+      <xsl:when test="property">
+        <h2 xmlns="http://www.w3.org/1999/xhtml">D-Bus core Properties:</h2>
+        <p xmlns="http://www.w3.org/1999/xhtml">Accessed using the
+          org.freedesktop.DBus.Properties interface.</p>
+        <dl xmlns="http://www.w3.org/1999/xhtml">
+          <xsl:apply-templates select="property"/>
+        </dl>
+      </xsl:when>
+      <xsl:otherwise>
+        <p xmlns="http://www.w3.org/1999/xhtml">Interface has no D-Bus core
+          properties.</p>
       </xsl:otherwise>
     </xsl:choose>
 
@@ -156,12 +308,30 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   </xsl:template>
 
   <xsl:template match="tp:flags">
+
+    <xsl:if test="not(@name) or @name = ''">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: missing @name on a tp:flags type&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
+    <xsl:if test="not(@type) or @type = ''">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: missing @type on tp:flags type</xsl:text>
+        <xsl:value-of select="@name"/>
+        <xsl:text>&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
     <h3>
       <a name="type-{@name}">
         <xsl:value-of select="@name"/>
       </a>
     </h3>
     <xsl:apply-templates select="tp:docstring" />
+    <xsl:apply-templates select="tp:added"/>
+    <xsl:apply-templates select="tp:changed"/>
+    <xsl:apply-templates select="tp:deprecated"/>
     <dl xmlns="http://www.w3.org/1999/xhtml">
         <xsl:variable name="value-prefix">
           <xsl:choose>
@@ -177,7 +347,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
         <dt xmlns="http://www.w3.org/1999/xhtml"><code><xsl:value-of select="concat($value-prefix, '_', @suffix)"/> = <xsl:value-of select="@value"/></code></dt>
         <xsl:choose>
           <xsl:when test="tp:docstring">
-            <dd xmlns="http://www.w3.org/1999/xhtml"><xsl:apply-templates select="tp:docstring" /></dd>
+            <dd xmlns="http://www.w3.org/1999/xhtml">
+              <xsl:apply-templates select="tp:docstring" />
+              <xsl:apply-templates select="tp:added"/>
+              <xsl:apply-templates select="tp:changed"/>
+              <xsl:apply-templates select="tp:deprecated"/>
+            </dd>
           </xsl:when>
           <xsl:otherwise>
             <dd xmlns="http://www.w3.org/1999/xhtml">(Undocumented)</dd>
@@ -188,12 +363,30 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   </xsl:template>
 
   <xsl:template match="tp:enum">
+
+    <xsl:if test="not(@name) or @name = ''">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: missing @name on a tp:enum type&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
+    <xsl:if test="not(@type) or @type = ''">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: missing @type on tp:enum type</xsl:text>
+        <xsl:value-of select="@name"/>
+        <xsl:text>&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
     <h3 xmlns="http://www.w3.org/1999/xhtml">
       <a name="type-{@name}">
         <xsl:value-of select="@name"/>
       </a>
     </h3>
     <xsl:apply-templates select="tp:docstring" />
+    <xsl:apply-templates select="tp:added"/>
+    <xsl:apply-templates select="tp:changed"/>
+    <xsl:apply-templates select="tp:deprecated"/>
     <dl xmlns="http://www.w3.org/1999/xhtml">
         <xsl:variable name="value-prefix">
           <xsl:choose>
@@ -209,7 +402,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
         <dt xmlns="http://www.w3.org/1999/xhtml"><code><xsl:value-of select="concat($value-prefix, '_', @suffix)"/> = <xsl:value-of select="@value"/></code></dt>
         <xsl:choose>
           <xsl:when test="tp:docstring">
-            <dd xmlns="http://www.w3.org/1999/xhtml"><xsl:apply-templates select="tp:docstring" /></dd>
+            <dd xmlns="http://www.w3.org/1999/xhtml">
+              <xsl:apply-templates select="tp:docstring" />
+              <xsl:apply-templates select="tp:added"/>
+              <xsl:apply-templates select="tp:changed"/>
+              <xsl:apply-templates select="tp:deprecated"/>
+            </dd>
           </xsl:when>
           <xsl:otherwise>
             <dd xmlns="http://www.w3.org/1999/xhtml">(Undocumented)</dd>
@@ -219,15 +417,84 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     </dl>
   </xsl:template>
 
+  <xsl:template match="property">
+
+    <xsl:if test="not(parent::interface)">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: property </xsl:text>
+        <xsl:value-of select="@name"/>
+        <xsl:text> does not have an interface as parent&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
+    <xsl:if test="not(@name) or @name = ''">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: missing @name on a property of </xsl:text>
+        <xsl:value-of select="../@name"/>
+        <xsl:text>&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
+    <xsl:if test="not(@type) or @type = ''">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: missing @type on property </xsl:text>
+        <xsl:value-of select="concat(../@name, '.', @name)"/>
+        <xsl:text>: '</xsl:text>
+        <xsl:value-of select="@access"/>
+        <xsl:text>'&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
+    <dt xmlns="http://www.w3.org/1999/xhtml">
+      <a name="{concat(../@name, '.', @name)}">
+        <code><xsl:value-of select="@name"/></code>
+      </a>
+      <xsl:text> − </xsl:text>
+      <code><xsl:value-of select="@type"/></code>
+      <xsl:call-template name="parenthesized-tp-type"/>
+      <xsl:text>, </xsl:text>
+      <xsl:choose>
+        <xsl:when test="@access = 'read'">
+          <xsl:text>read-only</xsl:text>
+        </xsl:when>
+        <xsl:when test="@access = 'write'">
+          <xsl:text>write-only</xsl:text>
+        </xsl:when>
+        <xsl:when test="@access = 'readwrite'">
+          <xsl:text>read/write</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:message terminate="yes">
+            <xsl:text>ERR: unknown or missing value for </xsl:text>
+            <xsl:text>@access on property </xsl:text>
+            <xsl:value-of select="concat(../@name, '.', @name)"/>
+            <xsl:text>: '</xsl:text>
+            <xsl:value-of select="@access"/>
+            <xsl:text>'&#10;</xsl:text>
+          </xsl:message>
+        </xsl:otherwise>
+      </xsl:choose>
+    </dt>
+    <dd xmlns="http://www.w3.org/1999/xhtml">
+      <xsl:apply-templates select="tp:docstring"/>
+      <xsl:apply-templates select="tp:added"/>
+      <xsl:apply-templates select="tp:changed"/>
+      <xsl:apply-templates select="tp:deprecated"/>
+    </dd>
+  </xsl:template>
+
   <xsl:template match="tp:property">
     <dt xmlns="http://www.w3.org/1999/xhtml">
       <xsl:if test="@name">
-        <code><xsl:value-of select="@name"/></code> -
+        <code><xsl:value-of select="@name"/></code> 
       </xsl:if>
       <code><xsl:value-of select="@type"/></code>
     </dt>
     <dd xmlns="http://www.w3.org/1999/xhtml">
       <xsl:apply-templates select="tp:docstring"/>
+      <xsl:apply-templates select="tp:added"/>
+      <xsl:apply-templates select="tp:changed"/>
+      <xsl:apply-templates select="tp:deprecated"/>
     </dd>
   </xsl:template>
 
@@ -236,7 +503,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       <h3>
         <a name="type-{@name}">
           <xsl:value-of select="@name"/>
-        </a> - a{
+        </a>  a{
         <xsl:for-each select="tp:member">
           <xsl:value-of select="@type"/>
           <xsl:text>: </xsl:text>
@@ -247,6 +514,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       </h3>
       <div class="docstring">
         <xsl:apply-templates select="tp:docstring"/>
+        <xsl:if test="string(@array-name) != ''">
+          <p>In bindings that need a separate name, arrays of
+            <xsl:value-of select="@name"/> should be called
+            <xsl:value-of select="@array-name"/>.</p>
+        </xsl:if>
       </div>
       <div>
         <h4>Members</h4>
@@ -261,42 +533,75 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
   <xsl:template match="tp:simple-type | tp:enum | tp:flags | tp:external-type"
     mode="in-index">
-    - <xsl:value-of select="@type"/>
+     <xsl:value-of select="@type"/>
   </xsl:template>
 
   <xsl:template match="tp:simple-type">
+
+    <xsl:if test="not(@name) or @name = ''">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: missing @name on a tp:simple-type&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
+    <xsl:if test="not(@type) or @type = ''">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: missing @type on tp:simple-type</xsl:text>
+        <xsl:value-of select="@name"/>
+        <xsl:text>&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
     <div xmlns="http://www.w3.org/1999/xhtml" class="simple-type">
       <h3>
         <a name="type-{@name}">
           <xsl:value-of select="@name"/>
-        </a> - <xsl:value-of select="@type"/>
+        </a>  <xsl:value-of select="@type"/>
       </h3>
       <div class="docstring">
         <xsl:apply-templates select="tp:docstring"/>
+        <xsl:apply-templates select="tp:added"/>
+        <xsl:apply-templates select="tp:changed"/>
+        <xsl:apply-templates select="tp:deprecated"/>
       </div>
     </div>
   </xsl:template>
 
   <xsl:template match="tp:external-type">
+
+    <xsl:if test="not(@name) or @name = ''">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: missing @name on a tp:external-type&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
+    <xsl:if test="not(@type) or @type = ''">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: missing @type on tp:external-type</xsl:text>
+        <xsl:value-of select="@name"/>
+        <xsl:text>&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
     <div xmlns="http://www.w3.org/1999/xhtml" class="external-type">
       <dt>
         <a name="type-{@name}">
           <xsl:value-of select="@name"/>
-        </a> - <xsl:value-of select="@type"/>
+        </a>  <xsl:value-of select="@type"/>
       </dt>
       <dd>Defined by: <xsl:value-of select="@from"/></dd>
     </div>
   </xsl:template>
 
   <xsl:template match="tp:struct" mode="in-index">
-    - ( <xsl:for-each select="tp:member">
+     ( <xsl:for-each select="tp:member">
           <xsl:value-of select="@type"/>
           <xsl:if test="position() != last()">, </xsl:if>
         </xsl:for-each> )
   </xsl:template>
 
   <xsl:template match="tp:mapping" mode="in-index">
-    - a{ <xsl:for-each select="tp:member">
+     a{ <xsl:for-each select="tp:member">
           <xsl:value-of select="@type"/>
           <xsl:if test="position() != last()"> &#x2192; </xsl:if>
         </xsl:for-each> }
@@ -307,7 +612,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       <h3>
         <a name="type-{@name}">
           <xsl:value-of select="@name"/>
-        </a> - (
+        </a>  (
         <xsl:for-each select="tp:member">
           <xsl:value-of select="@type"/>
           <xsl:text>: </xsl:text>
@@ -318,6 +623,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       </h3>
       <div class="docstring">
         <xsl:apply-templates select="tp:docstring"/>
+        <xsl:apply-templates select="tp:added"/>
+        <xsl:apply-templates select="tp:changed"/>
+        <xsl:apply-templates select="tp:deprecated"/>
       </div>
       <xsl:choose>
         <xsl:when test="string(@array-name) != ''">
@@ -340,6 +648,64 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   </xsl:template>
 
   <xsl:template match="method">
+
+    <xsl:if test="not(parent::interface)">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: method </xsl:text>
+        <xsl:value-of select="@name"/>
+        <xsl:text> does not have an interface as parent&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
+    <xsl:if test="not(@name) or @name = ''">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: missing @name on a method of </xsl:text>
+        <xsl:value-of select="../@name"/>
+        <xsl:text>&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
+    <xsl:for-each select="arg">
+      <xsl:if test="not(@type) or @type = ''">
+        <xsl:message terminate="yes">
+          <xsl:text>ERR: an arg of method </xsl:text>
+          <xsl:value-of select="concat(../../@name, '.', ../@name)"/>
+          <xsl:text> has no type</xsl:text>
+        </xsl:message>
+      </xsl:if>
+      <xsl:choose>
+        <xsl:when test="@direction='in'">
+          <xsl:if test="not(@name) or @name = ''">
+            <xsl:message terminate="yes">
+              <xsl:text>ERR: an 'in' arg of method </xsl:text>
+              <xsl:value-of select="concat(../../@name, '.', ../@name)"/>
+              <xsl:text> has no name</xsl:text>
+            </xsl:message>
+          </xsl:if>
+        </xsl:when>
+        <xsl:when test="@direction='out'">
+          <!-- FIXME: This is commented out until someone with a lot of time
+          on their hands goes through the spec adding names to all the "out"
+          arguments
+
+          <xsl:if test="not(@name) or @name = ''">
+            <xsl:message terminate="no">
+              <xsl:text>INFO: an 'out' arg of method </xsl:text>
+              <xsl:value-of select="concat(../../@name, '.', ../@name)"/>
+              <xsl:text> has no name</xsl:text>
+            </xsl:message>
+          </xsl:if>-->
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:message terminate="yes">
+            <xsl:text>ERR: an arg of method </xsl:text>
+            <xsl:value-of select="concat(../../@name, '.', ../@name)"/>
+            <xsl:text> has direction neither 'in' nor 'out'</xsl:text>
+          </xsl:message>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:for-each>
+
     <div xmlns="http://www.w3.org/1999/xhtml" class="method">
       <h3 xmlns="http://www.w3.org/1999/xhtml">
         <a name="{concat(../@name, concat('.', @name))}">
@@ -362,6 +728,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       </h3>
       <div xmlns="http://www.w3.org/1999/xhtml" class="docstring">
         <xsl:apply-templates select="tp:docstring" />
+        <xsl:apply-templates select="tp:added"/>
+        <xsl:apply-templates select="tp:changed"/>
+        <xsl:apply-templates select="tp:deprecated"/>
       </div>
 
       <xsl:if test="arg[@direction='in']">
@@ -396,31 +765,55 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     </div>
   </xsl:template>
 
-  <xsl:template name="parenthesized-tp-type">
-    <xsl:if test="@tp:type">
-      <xsl:variable name="tp-type" select="@tp:type"/>
-      <xsl:variable name="single-type">
-        <xsl:choose>
-          <xsl:when test="contains($tp-type, '[]')">
-            <xsl:value-of select="substring-before($tp-type, '[]')"/>
-          </xsl:when>
-          <xsl:otherwise>
-            <xsl:value-of select="$tp-type"/>
-          </xsl:otherwise>
-        </xsl:choose>
-      </xsl:variable>
+  <xsl:template name="tp-type">
+    <xsl:param name="tp-type"/>
+    <xsl:param name="type"/>
+
+    <xsl:variable name="single-type">
+      <xsl:choose>
+        <xsl:when test="contains($tp-type, '[]')">
+          <xsl:value-of select="substring-before($tp-type, '[]')"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="$tp-type"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+
+    <xsl:variable name="type-of-tp-type">
+      <xsl:if test="contains($tp-type, '[]')">
+        <!-- one 'a', plus one for each [ after the [], and delete all ] -->
+        <xsl:value-of select="concat('a',
+          translate(substring-after($tp-type, '[]'), '[]', 'a'))"/>
+      </xsl:if>
+
       <xsl:choose>
-        <xsl:when test="//tp:simple-type[@name=$tp-type]" />
-        <xsl:when test="//tp:simple-type[concat(@name, '[]')=$tp-type]" />
-        <xsl:when test="//tp:struct[concat(@name, '[]')=$tp-type][string(@array-name) != '']" />
-        <xsl:when test="//tp:struct[@name=$tp-type]" />
-        <xsl:when test="//tp:enum[@name=$tp-type]" />
-        <xsl:when test="//tp:enum[concat(@name, '[]')=$tp-type]" />
-        <xsl:when test="//tp:flags[@name=$tp-type]" />
-        <xsl:when test="//tp:flags[concat(@name, '[]')=$tp-type]" />
-        <xsl:when test="//tp:mapping[@name=$tp-type]" />
-        <xsl:when test="//tp:external-type[concat(@name, '[]')=$tp-type]" />
-        <xsl:when test="//tp:external-type[@name=$tp-type]" />
+        <xsl:when test="//tp:simple-type[@name=$single-type]">
+          <xsl:value-of select="string(//tp:simple-type[@name=$single-type]/@type)"/>
+        </xsl:when>
+        <xsl:when test="//tp:struct[@name=$single-type]">
+          <xsl:text>(</xsl:text>
+          <xsl:for-each select="//tp:struct[@name=$single-type]/tp:member">
+            <xsl:value-of select="@type"/>
+          </xsl:for-each>
+          <xsl:text>)</xsl:text>
+        </xsl:when>
+        <xsl:when test="//tp:enum[@name=$single-type]">
+          <xsl:value-of select="string(//tp:enum[@name=$single-type]/@type)"/>
+        </xsl:when>
+        <xsl:when test="//tp:flags[@name=$single-type]">
+          <xsl:value-of select="string(//tp:flags[@name=$single-type]/@type)"/>
+        </xsl:when>
+        <xsl:when test="//tp:mapping[@name=$single-type]">
+          <xsl:text>a{</xsl:text>
+          <xsl:for-each select="//tp:mapping[@name=$single-type]/tp:member">
+            <xsl:value-of select="@type"/>
+          </xsl:for-each>
+          <xsl:text>}</xsl:text>
+        </xsl:when>
+        <xsl:when test="//tp:external-type[@name=$single-type]">
+          <xsl:value-of select="string(//tp:external-type[@name=$single-type]/@type)"/>
+        </xsl:when>
         <xsl:otherwise>
           <xsl:message terminate="yes">
             <xsl:text>ERR: Unable to find type '</xsl:text>
@@ -429,13 +822,39 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
           </xsl:message>
         </xsl:otherwise>
       </xsl:choose>
-      (<a href="#type-{$single-type}"><xsl:value-of select="$tp-type"/></a>)
+    </xsl:variable>
+
+    <xsl:if test="string($type) != '' and
+      string($type-of-tp-type) != string($type)">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: tp:type '</xsl:text>
+        <xsl:value-of select="$tp-type"/>
+        <xsl:text>' has D-Bus type '</xsl:text>
+        <xsl:value-of select="$type-of-tp-type"/>
+        <xsl:text>' but has been used with type='</xsl:text>
+        <xsl:value-of select="$type"/>
+        <xsl:text>'&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
+    <a href="#type-{$single-type}"><xsl:value-of select="$tp-type"/></a>
+
+  </xsl:template>
+
+  <xsl:template name="parenthesized-tp-type">
+    <xsl:if test="@tp:type">
+      <xsl:text> (</xsl:text>
+      <xsl:call-template name="tp-type">
+        <xsl:with-param name="tp-type" select="@tp:type"/>
+        <xsl:with-param name="type" select="@type"/>
+      </xsl:call-template>
+      <xsl:text>)</xsl:text>
     </xsl:if>
   </xsl:template>
 
   <xsl:template match="tp:member" mode="members-in-docstring">
     <dt xmlns="http://www.w3.org/1999/xhtml">
-      <code><xsl:value-of select="@name"/></code> -
+      <code><xsl:value-of select="@name"/></code> 
       <code><xsl:value-of select="@type"/></code>
       <xsl:call-template name="parenthesized-tp-type"/>
     </dt>
@@ -453,7 +872,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
   <xsl:template match="arg" mode="parameters-in-docstring">
     <dt xmlns="http://www.w3.org/1999/xhtml">
-      <code><xsl:value-of select="@name"/></code> -
+      <code><xsl:value-of select="@name"/></code> 
       <code><xsl:value-of select="@type"/></code>
       <xsl:call-template name="parenthesized-tp-type"/>
     </dt>
@@ -465,7 +884,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   <xsl:template match="arg" mode="returns-in-docstring">
     <dt xmlns="http://www.w3.org/1999/xhtml">
       <xsl:if test="@name">
-        <code><xsl:value-of select="@name"/></code> -
+        <code><xsl:value-of select="@name"/></code> 
       </xsl:if>
       <code><xsl:value-of select="@type"/></code>
       <xsl:call-template name="parenthesized-tp-type"/>
@@ -496,6 +915,57 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   </xsl:template>
 
   <xsl:template match="signal">
+
+    <xsl:if test="not(parent::interface)">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: signal </xsl:text>
+        <xsl:value-of select="@name"/>
+        <xsl:text> does not have an interface as parent&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
+    <xsl:if test="not(@name) or @name = ''">
+      <xsl:message terminate="yes">
+        <xsl:text>ERR: missing @name on a signal of </xsl:text>
+        <xsl:value-of select="../@name"/>
+        <xsl:text>&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+
+    <xsl:for-each select="arg">
+      <xsl:if test="not(@type) or @type = ''">
+        <xsl:message terminate="yes">
+          <xsl:text>ERR: an arg of signal </xsl:text>
+          <xsl:value-of select="concat(../../@name, '.', ../@name)"/>
+          <xsl:text> has no type</xsl:text>
+        </xsl:message>
+      </xsl:if>
+      <xsl:if test="not(@name) or @name = ''">
+        <xsl:message terminate="yes">
+          <xsl:text>ERR: an arg of signal </xsl:text>
+          <xsl:value-of select="concat(../../@name, '.', ../@name)"/>
+          <xsl:text> has no name</xsl:text>
+        </xsl:message>
+      </xsl:if>
+      <xsl:choose>
+        <xsl:when test="not(@direction)"/>
+        <xsl:when test="@direction='in'">
+          <xsl:message terminate="no">
+            <xsl:text>INFO: an arg of signal </xsl:text>
+            <xsl:value-of select="concat(../../@name, '.', ../@name)"/>
+            <xsl:text> has unnecessary direction 'in'</xsl:text>
+          </xsl:message>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:message terminate="yes">
+            <xsl:text>ERR: an arg of signal </xsl:text>
+            <xsl:value-of select="concat(../../@name, '.', ../@name)"/>
+            <xsl:text> has direction other than 'in'</xsl:text>
+          </xsl:message>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:for-each>
+
     <div xmlns="http://www.w3.org/1999/xhtml" class="signal">
       <h3 xmlns="http://www.w3.org/1999/xhtml">
         <a name="{concat(../@name, concat('.', @name))}">
@@ -506,8 +976,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
           <xsl:if test="position() != last()">, </xsl:if>
         </xsl:for-each>
         )</h3>
+
       <div xmlns="http://www.w3.org/1999/xhtml" class="docstring">
         <xsl:apply-templates select="tp:docstring"/>
+        <xsl:apply-templates select="tp:added"/>
+        <xsl:apply-templates select="tp:changed"/>
+        <xsl:apply-templates select="tp:deprecated"/>
       </div>
 
       <xsl:if test="arg">
@@ -626,13 +1100,26 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
             float: right;
             font-style: italic;
           }
-          .method {
+          .method, .signal, .property {
             margin-left: 1em;
             margin-right: 4em;
           }
-          .signal {
-            margin-left: 1em;
-            margin-right: 4em;
+          .rationale {
+            font-style: italic;
+            border-left: 0.25em solid #808080;
+            padding-left: 0.5em;
+          }
+
+          .added {
+            color: #006600;
+            background: #ffffff;
+          }
+          .deprecated {
+            color: #ff0000;
+            background: #ffffff;
+          }
+          table, tr, td, th {
+            border: 1px solid #666;
           }
 
         </style>
@@ -642,7 +1129,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
           <xsl:value-of select="tp:title" />
         </h1>
         <xsl:if test="tp:version">
-          <h2>Version <xsl:apply-templates select="tp:version"/></h2>
+          <h2>Version <xsl:value-of select="string(tp:version)"/></h2>
         </xsl:if>
         <xsl:apply-templates select="tp:copyright"/>
         <xsl:apply-templates select="tp:license"/>
@@ -650,19 +1137,19 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
         <h2>Interfaces</h2>
         <ul>
-        <xsl:for-each select="node/interface">
+          <xsl:for-each select="//node/interface">
             <li><code><a href="#{@name}"><xsl:value-of select="@name"/></a></code></li>
           </xsl:for-each>
         </ul>
 
-        <xsl:apply-templates select="node"/>
+        <xsl:apply-templates select="//node"/>
         <xsl:apply-templates select="tp:generic-types"/>
         <xsl:apply-templates select="tp:errors"/>
 
         <h1>Index</h1>
         <h2>Index of interfaces</h2>
         <ul>
-        <xsl:for-each select="node/interface">
+          <xsl:for-each select="//node/interface">
             <li><code><a href="#{@name}"><xsl:value-of select="@name"/></a></code></li>
           </xsl:for-each>
         </ul>
@@ -684,6 +1171,29 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     </html>
   </xsl:template>
 
+  <xsl:template match="node">
+      <xsl:apply-templates />
+  </xsl:template>
+
+  <xsl:template match="text()">
+    <xsl:if test="normalize-space(.) != ''">
+      <xsl:message terminate="yes">
+        <xsl:text>Stray text: {{{</xsl:text>
+        <xsl:value-of select="." />
+        <xsl:text>}}}&#10;</xsl:text>
+      </xsl:message>
+    </xsl:if>
+  </xsl:template>
+
+  <xsl:template match="*">
+      <xsl:message terminate="yes">
+         <xsl:text>Unrecognised element: {</xsl:text>
+         <xsl:value-of select="namespace-uri(.)" />
+         <xsl:text>}</xsl:text>
+         <xsl:value-of select="local-name(.)" />
+         <xsl:text>&#10;</xsl:text>
+      </xsl:message>
+  </xsl:template>
 </xsl:stylesheet>
 
 <!-- vim:set sw=2 sts=2 et: -->