[gnome-doc-utils] Importing Mallard XSLT changes from yelp-xsl



commit d9255da2f836a7ee6ce7e37b578744fa304fb6c3
Author: Shaun McCance <shaunm gnome org>
Date:   Tue Jan 5 16:39:15 2010 -0600

    Importing Mallard XSLT changes from yelp-xsl

 configure.in                          |    2 +-
 tools/gnome-doc-tool.in               |   10 +-
 xslt/mallard/Makefile.am              |    2 +-
 xslt/mallard/cache/Makefile.am        |    5 +
 xslt/mallard/cache/mal-cache.xsl      |  192 ++++++++++++
 xslt/mallard/common/mal-chunk.xsl     |    7 +
 xslt/mallard/common/mal-link.xsl      |  520 ++++++++++++++++++++++++++++-----
 xslt/mallard/html/mal2html-block.xsl  |    7 +
 xslt/mallard/html/mal2html-css.xsl    |   34 ++-
 xslt/mallard/html/mal2html-inline.xsl |    9 +-
 xslt/mallard/html/mal2html-list.xsl   |   28 ++
 xslt/mallard/html/mal2html-media.xsl  |  151 ++++++++--
 xslt/mallard/html/mal2html-page.xsl   |  391 ++++++++++++-------------
 xslt/mallard/utils/Makefile.am        |    5 -
 xslt/mallard/utils/mal2cache.xsl      |  119 --------
 15 files changed, 1036 insertions(+), 446 deletions(-)
---
diff --git a/configure.in b/configure.in
index 68fb8d4..c12bbaa 100644
--- a/configure.in
+++ b/configure.in
@@ -77,9 +77,9 @@ xslt/docbook/html/Makefile
 xslt/docbook/omf/Makefile
 xslt/docbook/utils/Makefile
 xslt/mallard/Makefile
+xslt/mallard/cache/Makefile
 xslt/mallard/common/Makefile
 xslt/mallard/html/Makefile
-xslt/mallard/utils/Makefile
 xslt/gettext/Makefile
 ])
 
diff --git a/tools/gnome-doc-tool.in b/tools/gnome-doc-tool.in
index 00d30a5..c836517 100644
--- a/tools/gnome-doc-tool.in
+++ b/tools/gnome-doc-tool.in
@@ -111,13 +111,13 @@ XSL_ICONS='
 XSL_CACHE_LS='
 <xsl:stylesheet
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
-  xmlns:cache="http://projectmallard.org/1.0/";
+  xmlns:cache="http://projectmallard.org/cache/1.0/";
   xmlns:mal="http://projectmallard.org/1.0/";
   version="1.0">
 <xsl:output method="text"/>
 <xsl:template match="/">
   <xsl:for-each select="cache:cache/mal:page">
-    <xsl:value-of select="@href"/>
+    <xsl:value-of select="@cache:href"/>
     <xsl:text>&#x000A;</xsl:text>
   </xsl:for-each>
 </xsl:template>
@@ -428,7 +428,7 @@ convert_mallard2html() {
     doc_cache="$doc_outdir/index.cache"
     doc_tmpfiles="$doc_tmpfiles doc_cache_in doc_cache_out"
     (
-	echo '<cache:cache xmlns:cache="http://projectmallard.org/1.0/";'
+	echo '<cache:cache xmlns:cache="http://projectmallard.org/cache/1.0/";'
 	echo '             xmlns="http://projectmallard.org/1.0/";>'
 	while [ "$#" != "0" ]; do
 	    doc_input="$1"
@@ -444,11 +444,11 @@ convert_mallard2html() {
 	    fi
 	done | while read doc_input; do
 	    doc_input_esc=$(urlencode "$doc_input" | sed -e 's/\&/\&amp;/g' -e 's/</\&lt;/g' -e "s/'/\&apos;/g")
-	    echo "<page href='file://$doc_input_esc'/>"
+	    echo "<page cache:href='file://$doc_input_esc'/>"
 	done
 	echo '</cache:cache>'
     ) > "$doc_cache_in"
-    xsltproc -o "$doc_cache" "$xsltdir/mallard/utils/mal2cache.xsl" "$doc_cache_in"
+    xsltproc -o "$doc_cache" "$xsltdir/mallard/cache/mal-cache.xsl" "$doc_cache_in"
     rm "$doc_cache_in"
     echo "$XSL_CACHE_LS" | xsltproc - "$doc_cache" | while read doc_input; do
 	doc_input=$(urldecode $(echo "$doc_input" | sed -e 's/^file:\/\///'))
diff --git a/xslt/mallard/Makefile.am b/xslt/mallard/Makefile.am
index 5d6f8e2..895e009 100644
--- a/xslt/mallard/Makefile.am
+++ b/xslt/mallard/Makefile.am
@@ -1 +1 @@
-SUBDIRS = common html utils
+SUBDIRS = cache common html
diff --git a/xslt/mallard/cache/Makefile.am b/xslt/mallard/cache/Makefile.am
new file mode 100644
index 0000000..8da433d
--- /dev/null
+++ b/xslt/mallard/cache/Makefile.am
@@ -0,0 +1,5 @@
+xsldir=$(datadir)/xml/gnome/xslt/mallard/cache
+
+xsl_DATA = mal-cache.xsl
+
+EXTRA_DIST=$(xsl_DATA)
diff --git a/xslt/mallard/cache/mal-cache.xsl b/xslt/mallard/cache/mal-cache.xsl
new file mode 100644
index 0000000..3357909
--- /dev/null
+++ b/xslt/mallard/cache/mal-cache.xsl
@@ -0,0 +1,192 @@
+<?xml version='1.0' encoding='UTF-8'?><!-- -*- indent-tabs-mode: nil -*- -->
+<!--
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option) any
+later version.
+
+This program 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 Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program; see the file COPYING.LGPL.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
+-->
+
+<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
+                xmlns:mal='http://projectmallard.org/1.0/'
+                xmlns:cache='http://projectmallard.org/cache/1.0/'
+                xmlns='http://projectmallard.org/1.0/'
+                version='1.0'>
+
+<!--!!==========================================================================
+Mallard Cache Files
+Generate Mallard cache files from cache input files.
+
+FIXME
+-->
+
+<xsl:output omit-xml-declaration="yes"/>
+
+<xsl:include href="../common/mal-link.xsl"/>
+
+
+<!--**==========================================================================
+mal.cache.id
+-->
+<xsl:template name="mal.cache.id">
+  <xsl:param name="node" select="."/>
+  <xsl:param name="node_in"/>
+  <xsl:attribute name="id">
+    <xsl:call-template name="mal.link.linkid">
+      <xsl:with-param name="node" select="$node"/>
+    </xsl:call-template>
+  </xsl:attribute>
+</xsl:template>
+
+
+<!--**==========================================================================
+mal.cache.xref
+-->
+<xsl:template name="mal.cache.xref">
+  <xsl:param name="node" select="."/>
+  <xsl:param name="node_in"/>
+  <xsl:attribute name="xref">
+    <xsl:value-of select="$node/@xref"/>
+  </xsl:attribute>
+</xsl:template>
+
+
+<!--**==========================================================================
+mal.cache.groups
+-->
+<xsl:template name="mal.cache.groups">
+  <xsl:param name="node" select="."/>
+  <xsl:param name="node_in"/>
+  <xsl:attribute name="groups">
+    <xsl:value-of select="$node/@groups"/>
+    <xsl:if test="not(contains(concat(' ', $node/@groups, ' '), ' #default '))">
+      <xsl:text> #default</xsl:text>
+    </xsl:if>
+  </xsl:attribute>
+</xsl:template>
+
+
+<!--**==========================================================================
+mal.cache.info
+-->
+<xsl:template name="mal.cache.info">
+  <xsl:param name="node" select="."/>
+  <xsl:param name="info" select="$node/mal:info"/>
+  <xsl:param name="node_in"/>
+  <info>
+    <xsl:if test="not($info/mal:title[ type = 'link'])">
+      <title type="link">
+        <xsl:copy-of select="$node/mal:title/node()"/>
+      </title>
+    </xsl:if>
+    <xsl:if test="not($info/mal:title[ type = 'sort'])">
+      <title type="sort">
+        <xsl:choose>
+          <xsl:when test="$info/mal:title[ type = 'link']">
+            <xsl:copy-of select="$info/mal:title[ type = 'link'][1]/node()"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:copy-of select="$node/mal:title/node()"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </title>
+    </xsl:if>
+    <xsl:for-each select="$info/*">
+      <xsl:choose>
+        <xsl:when test="self::mal:link">
+          <link>
+            <xsl:call-template name="mal.cache.xref">
+              <xsl:with-param name="node_in" select="$node_in"/>
+            </xsl:call-template>
+            <xsl:if test="@type = 'guide' and not(@weight)">
+              <xsl:attribute name="weight">
+                <xsl:text>0</xsl:text>
+              </xsl:attribute>
+            </xsl:if>
+            <xsl:for-each select="attribute::*[not(name(.) = 'xref')] | *">
+              <xsl:copy-of select="."/>
+            </xsl:for-each>
+          </link>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:copy-of select="."/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:for-each>
+  </info>
+</xsl:template>
+
+
+<!-- == Matched Templates == -->
+
+<!-- = /cache:cache = -->
+<xsl:template match='/cache:cache'>
+  <cache:cache>
+    <xsl:for-each select="mal:page">
+      <xsl:apply-templates select="document(@cache:href)/*">
+        <xsl:with-param name="node_in" select="."/>
+      </xsl:apply-templates>
+    </xsl:for-each>
+  </cache:cache>
+</xsl:template>
+
+<!-- = mal:page = -->
+<xsl:template match="mal:page">
+  <xsl:param name="node_in"/>
+  <page cache:href="{$node_in/@cache:href}">
+    <xsl:call-template name="mal.cache.id">
+      <xsl:with-param name="node_in" select="$node_in"/>
+    </xsl:call-template>
+    <xsl:call-template name="mal.cache.groups">
+      <xsl:with-param name="node_in" select="$node_in"/>
+    </xsl:call-template>
+    <xsl:if test="@type">
+      <xsl:attribute name="type">
+        <xsl:value-of select="@type"/>
+      </xsl:attribute>
+    </xsl:if>
+    <xsl:call-template name="mal.cache.info">
+      <xsl:with-param name="node_in" select="$node_in"/>
+    </xsl:call-template>
+    <xsl:apply-templates>
+      <xsl:with-param name="node_in" select="$node_in"/>
+    </xsl:apply-templates>
+  </page>
+</xsl:template>
+
+<!-- = mal:section = -->
+<xsl:template match="mal:section">
+  <xsl:param name="node_in"/>
+  <section>
+    <xsl:call-template name="mal.cache.id">
+      <xsl:with-param name="node_in" select="$node_in"/>
+    </xsl:call-template>
+    <xsl:call-template name="mal.cache.groups">
+      <xsl:with-param name="node_in" select="$node_in"/>
+    </xsl:call-template>
+    <xsl:call-template name="mal.cache.info">
+      <xsl:with-param name="node_in" select="$node_in"/>
+    </xsl:call-template>
+    <xsl:apply-templates>
+      <xsl:with-param name="node_in" select="$node_in"/>
+    </xsl:apply-templates>
+  </section>
+</xsl:template>
+
+<!-- = mal:title = -->
+<xsl:template match="mal:title">
+  <xsl:copy-of select="."/>
+</xsl:template>
+
+<xsl:template match="node() | text()"/>
+
+</xsl:stylesheet>
diff --git a/xslt/mallard/common/mal-chunk.xsl b/xslt/mallard/common/mal-chunk.xsl
index 72531c3..10265ff 100644
--- a/xslt/mallard/common/mal-chunk.xsl
+++ b/xslt/mallard/common/mal-chunk.xsl
@@ -82,4 +82,11 @@ REMARK: Describe
   </exsl:document>
 </xsl:template>
 
+<!--%%==========================================================================
+mal.chunk.content.mode
+FIXME
+
+FIXME
+-->
+
 </xsl:stylesheet>
diff --git a/xslt/mallard/common/mal-link.xsl b/xslt/mallard/common/mal-link.xsl
index 1a77439..ab4974d 100644
--- a/xslt/mallard/common/mal-link.xsl
+++ b/xslt/mallard/common/mal-link.xsl
@@ -17,71 +17,158 @@ Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 -->
 
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
+                xmlns:cache="http://projectmallard.org/cache/1.0/";
                 xmlns:mal="http://projectmallard.org/1.0/";
+                xmlns:exsl="http://exslt.org/common";
+                xmlns:str="http://exslt.org/strings";
                 version="1.0">
 
 <!--!!==========================================================================
 Mallard Links
+Common linking utilities for Mallard documents.
+:Revision:version="1.0" date="2010-01-02"
+
+This stylesheets contains various utilities for handling links in Mallard
+documents.  The templates in this stylesheet make it easier to handle the
+different linking mechanisms in Mallard, including the dynamic automatic
+linking systems.
 -->
 
 
 <!--@@==========================================================================
 mal.cache.file
-The location of the cache file
+The location of the cache file.
+:Revision:version="1.0" date="2010-01-02"
+
+In order to locate and process links between pages, this stylesheet requires
+a Mallard cache file.  Use this parameter to pass the path to a valid cache
+file.
 -->
 <xsl:param name="mal.cache.file"/>
-<xsl:param name="mal.cache" select="document($mal.cache.file)/mal:cache"/>
+
+
+<!--@@==========================================================================
+mal.cache
+The cache document as a node set.
+:Revision:version="1.0" date="2010-01-02"
+
+This parameter points to the root #{cache:cache} element of a Mallard cache
+document.  By default, it selects the root element from the file provided in
+ {mal cache file} 
+
+Some processing tools may create a Mallard cache document without outputting
+it to a file.  Those tools can use this parameter directly.
+-->
+<xsl:param name="mal.cache" select="document($mal.cache.file)/cache:cache"/>
+
+
+<!--============================================================================
+mal.cache.key
+-->
 <xsl:key name="mal.cache.key" match="mal:page | mal:section" use="@id"/>
 
 
+<!--@@==========================================================================
+mal.link.default_root
+The default root ID.
+
+This parameter provides the default ID for the page that is taken to be the
+root of the document.  By default, #{'index'} is used.  This should not be
+changed for normal Mallard documents.  It may be necessary to change it for
+some Mallard extension formats.
+-->
+<xsl:param name="mal.link.default_root" select="'index'"/>
+
+
 <!--**==========================================================================
-mal.link.content
-Generates the content for a #{link} element
-$link: The #{link} or other element creating the link
-$xref: The #{xref} attribute of ${link}
-$href: The #{href} attribute of ${link}
-$role: A link role, used to select the appropriate title
+mal.link.linkid
+Output the fully qualified link ID for a page or section.
+:Revision:version="1.0" date="2010-01-02"
+$node: The #{page} or #{section} element to generate a link ID for.
+
+This template outputs the fully qualified link ID for a page or section.  For
+#{page} elements, the link ID is identical to the ID.  For #{section} elements,
+however, the link ID is the containing page ID and the section ID, joined with
+the #{#} character.
+
+The link ID is used in Mallard cache files to ensure all #{id} attributes are
+unique.  All of the templates in this stylesheet that use a link ID use this
+template or *{mal.link.xref.linkid}.
 -->
-<xsl:template name="mal.link.content">
-  <xsl:param name="link" select="."/>
-  <xsl:param name="xref" select="$link/@xref"/>
-  <xsl:param name="href" select="$link/@href"/>
-  <xsl:param name="role" select="''"/>
+<xsl:template name="mal.link.linkid">
+  <xsl:param name="node" select="."/>
   <xsl:choose>
-    <xsl:when test="contains($xref, '/')">
-      <!--
-      This is a link to another document, which we don't handle in these
-      stylesheets.  Extensions such as library or yelp should override
-      this template to provide this functionality.
-      -->
-      <xsl:choose>
-        <xsl:when test="$href">
-          <xsl:value-of select="$href"/>
-        </xsl:when>
-        <xsl:otherwise>
-          <xsl:value-of select="$xref"/>
-        </xsl:otherwise>
-      </xsl:choose>
+    <xsl:when test="contains($node/@id, '#')">
+      <xsl:value-of select="$node/@id"/>
+    </xsl:when>
+    <xsl:when test="$node/self::mal:section">
+      <xsl:value-of select="concat($node/ancestor::mal:page[1]/@id, '#', $node/@id)"/>
     </xsl:when>
     <xsl:otherwise>
-      <xsl:variable name="fullid">
-        <xsl:choose>
-          <xsl:when test="contains($xref, '#')">
-            <xsl:variable name="pageid" select="substring-before($xref, '#')"/>
-            <xsl:variable name="sectionid" select="substring-after($xref, '#')"/>
-            <xsl:if test="$pageid = ''">
-              <xsl:value-of select="$link/ancestor::mal:page/@id"/>
-            </xsl:if>
-            <xsl:value-of select="concat($pageid, '#', $sectionid)"/>
-          </xsl:when>
-          <xsl:otherwise>
-            <xsl:value-of select="$xref"/>
-          </xsl:otherwise>
-        </xsl:choose>
-      </xsl:variable>
-      <xsl:for-each select="$mal.cache">
-        <xsl:variable name="titles" select="key('mal.cache.key', $fullid)
-                                           /mal:info/mal:title[ type = 'link']"/>
+      <xsl:value-of select="$node/@id"/>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+
+<!--**==========================================================================
+mal.link.xref.linkid
+Output the fully qualified link ID for an #{xref} attribute.
+:Revision:version="1.0" date="2010-01-02"
+$node: The element containing an #{xref} attribute.
+$xref: The #{xref} value to generate a link ID from.
+
+This template outputs the fully qualified link ID for an #{xref} attribute.
+This may simply be ${xref}, but if ${xref} starts with the #{#} character, it
+is prefixed with the ID of the page that contains ${node}.
+
+See *{mal.link.linkid} for more on link IDs.
+-->
+<xsl:template name="mal.link.xref.linkid">
+  <xsl:param name="node" select="."/>
+  <xsl:param name="xref" select="$node/@xref"/>
+  <xsl:if test="starts-with($xref, '#')">
+    <xsl:value-of select="$node/ancestor-or-self::mal:page/@id"/>
+  </xsl:if>
+  <xsl:value-of select="$xref"/>
+</xsl:template>
+
+
+<!--**==========================================================================
+mal.link.content
+Output the content for a #{link} element.
+:Revision:version="1.0" date="2010-01-02"
+$node: The #{link} or other element creating the link.
+$xref: The #{xref} attribute of ${node}.
+$href: The #{href} attribute of ${node}.
+$role: A link role, used to select the appropriate title.
+
+This template outputs the automatic text content for a link.  It should only
+be used for links that do not have specified content.  If ${xref} points to a
+valid page or section, the appropriate link title from that page or section
+will be selected, based on ${role}.  The %{mal.link.content.mode} mode will
+be applied to the contents of that title.  Stylesheets using this template
+should map that mode to inline processing.
+
+If only ${href} is provided, that URL is used as the text content.  If a target
+page or section cannot be found, ${xref} is used as the text content.
+-->
+<xsl:template name="mal.link.content">
+  <xsl:param name="node" select="."/>
+  <xsl:param name="xref" select="$node/@xref"/>
+  <xsl:param name="href" select="$node/@href"/>
+  <xsl:param name="role" select="''"/>
+  <xsl:variable name="linkid">
+    <xsl:call-template name="mal.link.xref.linkid">
+      <xsl:with-param name="node" select="$node"/>
+      <xsl:with-param name="xref" select="$xref"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:for-each select="$mal.cache">
+    <xsl:variable name="target" select="key('mal.cache.key', $linkid)"/>
+    <xsl:choose>
+      <xsl:when test="$target">
+        <xsl:variable name="titles" select="$target/mal:info/mal:title[ type = 'link']"/>
         <xsl:choose>
           <xsl:when test="$role != '' and $titles[ role = $role]">
             <xsl:apply-templates mode="mal.link.content.mode"
@@ -92,19 +179,30 @@ $role: A link role, used to select the appropriate title
                                  select="$titles[not(@role)][1]/node()"/>
           </xsl:otherwise>
         </xsl:choose>
-      </xsl:for-each>
-    </xsl:otherwise>
-  </xsl:choose>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:choose>
+          <xsl:when test="$href">
+            <xsl:value-of select="$href"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="$xref"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:for-each>
 </xsl:template>
 
 
 <!--%%==========================================================================
 mal.link.content.mode
-Renders the content of a link from a title
+Output the content for a link from the contents of a #{title} element.
+:Revision:version="1.0" date="2010-01-02"
 
 This mode is applied to the contents of a #{title} element by *{mal.link.content}.
-By default, it returns the string value of its input.  Stylesheets that import
-this module should override this to call their inline mode.
+By default, it returns the string value of its input.  Stylesheets that use
+*{mal.link.content} should map this mode to inline processing.
 -->
 <xsl:template mode="mal.link.content.mode" match="* | text()">
   <xsl:value-of select="."/>
@@ -113,20 +211,26 @@ this module should override this to call their inline mode.
 
 <!--**==========================================================================
 mal.link.target
-Generates the target for a #{link} element
-$link: The #{link} or other element creating the link
-$xref: The #{xref} attribute of ${link}
-$href: The #{href} attribute of ${link}
+Output the target URL for a #{link} or other linking element.
+:Revision:version="1.0" date="2010-01-02"
+$node: The #{link} or other element creating the link.
+$xref: The #{xref} attribute of ${node}.
+$href: The #{href} attribute of ${node}.
+
+This template outputs a URL for a #{link} element or another element using
+linking attributes.  If ${xref} points to a valid page or section, it uses
+a file name based on the ID of the target page plus @{mal.chunk.extension}.
+Otherwise, the link will point to ${href}.
 -->
 <xsl:template name="mal.link.target">
-  <xsl:param name="link" select="."/>
-  <xsl:param name="xref" select="$link/@xref"/>
-  <xsl:param name="href" select="$link/@href"/>
+  <xsl:param name="node" select="."/>
+  <xsl:param name="xref" select="$node/@xref"/>
+  <xsl:param name="href" select="$node/@href"/>
   <xsl:choose>
     <xsl:when test="string($xref) = ''">
       <xsl:value-of select="$href"/>
     </xsl:when>
-    <xsl:when test="contains($xref, '/')">
+    <xsl:when test="contains($xref, '/') or contains($xref, ':')">
       <!--
       This is a link to another document, which we don't handle in these
       stylesheets.  Extensions such as library or yelp should override
@@ -151,18 +255,22 @@ $href: The #{href} attribute of ${link}
 
 <!--**==========================================================================
 mal.link.tooltip
-Generates the tooltip for a #{link} or other linking element
-$link: The #{link} or other element creating the link
-$xref: The #{xref} attribute of ${link}
-$href: The #{href} attribute of ${link}
+Output the tooltip for a #{link} or other linking element.
+:Revision:version="1.0" date="2010-01-02"
+$node: The #{link} or other element creating the link.
+$xref: The #{xref} attribute of ${node}.
+$href: The #{href} attribute of ${node}.
+
+This template outputs a tooltip for a link.  Currently, it only outputs a
+tooltip for #{mailto:} URLs in ${href}.
 -->
 <xsl:template name="mal.link.tooltip">
-  <xsl:param name="link" select="."/>
-  <xsl:param name="xref" select="$link/@xref"/>
-  <xsl:param name="href" select="$link/@href"/>
+  <xsl:param name="node" select="."/>
+  <xsl:param name="xref" select="$node/@xref"/>
+  <xsl:param name="href" select="$node/@href"/>
   <xsl:choose>
     <xsl:when test="string($xref) != ''">
-      <!-- FIXME -->
+      <!-- FIXME and make sure to update the docs -->
     </xsl:when>
     <xsl:when test="starts-with($href, 'mailto:')">
       <xsl:variable name="address" select="substring-after($href, 'mailto:')"/>
@@ -178,4 +286,282 @@ $href: The #{href} attribute of ${link}
   </xsl:choose>
 </xsl:template>
 
+
+<!--**==========================================================================
+mal.link.guidelinks
+Output the guide links for a page or section.
+:Revision:version="1.0" date="2010-01-02"
+$node: The #{page} or #{section} element to generate links for.
+
+This template outputs all the guide links for a page or section, whether
+declared as guide links in the page or section or as topic links from another
+guide page.  It outputs each of the links as a #{link} element within the
+Mallard namespace.  Each #{link} element has an #{xref} attribute pointing
+to the target page or section.
+
+Each #{link} element contains a #{title} with #{type="sort"} providing the
+sort title of the target page or section.  The results are not sorted when
+returned from this template.  Use #{xsl:sort} on the sort titles to sort
+the results.
+
+The output is a result tree fragment.  To use these results, call
+#{exsl:node-set} on them.
+-->
+<xsl:template name="mal.link.guidelinks">
+  <xsl:param name="node" select="."/>
+  <xsl:variable name="linkid">
+    <xsl:call-template name="mal.link.linkid">
+      <xsl:with-param name="node" select="$node"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:for-each select="$node/mal:info/mal:link[ type = 'guide']">
+    <xsl:variable name="linklinkid">
+      <xsl:call-template name="mal.link.xref.linkid"/>
+    </xsl:variable>
+    <mal:link xref="{$linklinkid}">
+      <mal:title type="sort">
+        <xsl:for-each select="$mal.cache">
+          <xsl:value-of select="key('mal.cache.key', $linklinkid)/mal:info/mal:title[ type = 'sort'][1]"/>
+        </xsl:for-each>
+      </mal:title>
+    </mal:link>
+  </xsl:for-each>
+  <xsl:for-each select="$mal.cache//*[mal:info/mal:link[ type = 'topic'][ xref = $linkid]]">
+    <xsl:variable name="linklinkid">
+      <xsl:call-template name="mal.link.linkid"/>
+    </xsl:variable>
+    <xsl:if test="not($node/mal:info/mal:link[ type = 'guide'][ xref = $linklinkid])">
+      <mal:link xref="{$linklinkid}">
+        <mal:title type="sort">
+          <xsl:value-of select="mal:info/mal:title[ type = 'sort'][1]"/>
+        </mal:title>
+      </mal:link>
+    </xsl:if>
+  </xsl:for-each>
+</xsl:template>
+
+
+<!--**==========================================================================
+mal.link.topiclinks
+Output the topic links for a page or section.
+:Revision:version="1.0" date="2010-01-02"
+$node: The #{page} or #{section} element to generate links for.
+
+This template outputs all the topic links for a guide page or section, whether
+declared as topic links in the page or section or as guide links from another
+page or section.  It outputs each of the links as a #{link} element within the
+Mallard namespace.  Each #{link} element has an #{xref} attribute pointing
+to the target page or section.
+
+Each #{link} element contains a #{title} with #{type="sort"} providing the
+sort title of the target page or section.
+
+Each #{link} element also contains a #{group} attribute.  The #{group}
+attribute is normalized.  It will either point to a link group declared
+in ${node}, or it will be set to #{#default}.  Each #{link} element also
+contains a #{groupsort} attribute giving the numerical position of the
+#{group} attribute in the normalized group list for ${node}.
+
+The results are not sorted when returned from this template.  Use #{xsl:sort}
+on the #{groupsort} attribute and the sort titles to sort the results.
+
+The output is a result tree fragment.  To use these results, call
+#{exsl:node-set} on them.
+-->
+<xsl:template name="mal.link.topiclinks">
+  <xsl:param name="node" select="."/>
+  <xsl:variable name="linkid">
+    <xsl:call-template name="mal.link.linkid">
+      <xsl:with-param name="node" select="$node"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:variable name="groups">
+    <xsl:value-of select="$node/@groups"/>
+    <xsl:if test="not(contains(concat(' ', $node/@groups, ' '), ' #default '))">
+      <xsl:text> #default</xsl:text>
+    </xsl:if>
+  </xsl:variable>
+  <xsl:variable name="groupslist" select="str:split($groups)"/>
+  <xsl:variable name="defaultpos">
+    <xsl:for-each select="$groupslist">
+      <xsl:if test="string(.) = '#default'">
+        <xsl:value-of select="position()"/>
+      </xsl:if>
+    </xsl:for-each>
+  </xsl:variable>
+  <xsl:for-each select="$node/mal:info/mal:link[ type = 'topic']">
+    <xsl:variable name="xref">
+      <xsl:call-template name="mal.link.xref.linkid"/>
+    </xsl:variable>
+    <xsl:variable name="link" select="."/>
+    <xsl:variable name="grouppos">
+      <xsl:if test="$link/@group">
+        <xsl:for-each select="$groupslist">
+          <xsl:if test="string(.) = $link/@group">
+            <xsl:value-of select="position()"/>
+          </xsl:if>
+        </xsl:for-each>
+      </xsl:if>
+    </xsl:variable>
+    <xsl:variable name="groupsort">
+      <xsl:value-of select="$grouppos"/>
+      <xsl:if test="string($grouppos) = ''">
+        <xsl:value-of select="$defaultpos"/>
+      </xsl:if>
+    </xsl:variable>
+    <mal:link xref="{$xref}">
+      <xsl:attribute name="group">
+        <xsl:value-of select="$groupslist[number($groupsort)]"/>
+      </xsl:attribute>
+      <xsl:attribute name="groupsort">
+        <xsl:value-of select="$groupsort"/>
+      </xsl:attribute>
+      <mal:title type="sort">
+        <xsl:for-each select="$mal.cache">
+          <xsl:value-of select="key('mal.cache.key', $xref)/mal:info/mal:title[ type = 'sort'][1]"/>
+        </xsl:for-each>
+      </mal:title>
+    </mal:link>
+  </xsl:for-each>
+  <xsl:for-each select="$mal.cache//mal:info/mal:link[ type = 'guide'][ xref = $linkid]">
+    <xsl:variable name="source" select="../.."/>
+    <xsl:variable name="xref">
+      <xsl:call-template name="mal.link.xref.linkid">
+        <xsl:with-param name="node" select="$source"/>
+        <xsl:with-param name="xref" select="$source/@id"/>
+      </xsl:call-template>
+    </xsl:variable>
+    <xsl:if test="not($node/mal:info/mal:link[ type = 'topic'][ xref = $xref])">
+      <xsl:variable name="link" select="."/>
+      <xsl:variable name="grouppos">
+        <xsl:if test="$link/@group">
+          <xsl:for-each select="$groupslist">
+            <xsl:if test="string(.) = $link/@group">
+              <xsl:value-of select="position()"/>
+            </xsl:if>
+          </xsl:for-each>
+        </xsl:if>
+      </xsl:variable>
+      <xsl:variable name="groupsort">
+        <xsl:value-of select="$grouppos"/>
+        <xsl:if test="string($grouppos) = ''">
+          <xsl:value-of select="$defaultpos"/>
+        </xsl:if>
+      </xsl:variable>
+      <mal:link xref="{$xref}">
+        <xsl:attribute name="group">
+          <xsl:value-of select="$groupslist[number($groupsort)]"/>
+        </xsl:attribute>
+        <xsl:attribute name="groupsort">
+          <xsl:value-of select="$groupsort"/>
+        </xsl:attribute>
+        <mal:title type="sort">
+          <xsl:value-of select="$source/mal:info/mal:title[ type = 'sort'][1]"/>
+        </mal:title>
+      </mal:link>
+    </xsl:if>
+  </xsl:for-each>
+</xsl:template>
+
+
+<!--**==========================================================================
+mal.link.linktrails
+Output link trails for a page or section.
+$node: The #{page} or #{section} element to generate links for.
+$trail: The link trail leading to ${node}.
+$root: The ID of the root page.
+
+This template outputs lists of links, where each list is a path of topic links
+that leads to ${node}.  Each link list is output as a #{link} element in the
+Mallard namespace with an #{xref} attribute pointing to the target page or
+section.  Each #{link} has a #{title} element with #{type="sort"} providing
+the sort title of the target page or section.
+
+Each #{link} element may also contain another #{link} element providing the
+next link in the trail.  Each of these links also contains a sort titles and
+may also contain another link.
+
+The results are not sorted when returned from this template.  Use #{xsl:sort}
+on the nested sort titles to sort the results.  The output is a result tree
+fragment.  To use these results, call #{exsl:node-set} on them.
+
+This template calls itself recursively.  It finds the guide links for ${node}
+using *{mal.link.guidelinks}.  It then calls *{mal.link.linktrails} on each
+guide, wrapping ${trail} with a link to the guide as the new ${trail} parameter.
+
+If there are no guide links for ${node} and ${node} is a #{section} element,
+this template calls itself on the containing page, wrapping ${trails} with a
+link to that page.  This #{link} element has the attribute #{child="section"}
+to indicate the link from it to its child is not a topic link.
+
+Recursion stops when the ID of ${node} is ${root}.  Link trails are only
+output if they reach ${root}.
+-->
+<!--
+FIXME:
+* Terminate at $root
+* Only output if we reach $root
+* Cycle detection
+-->
+<xsl:template name="mal.link.linktrails">
+  <xsl:param name="node" select="."/>
+  <xsl:param name="trail" select="/false"/>
+  <xsl:param name="root" select="$mal.link.default_root"/>
+  <xsl:variable name="guidelinks">
+    <xsl:call-template name="mal.link.guidelinks">
+      <xsl:with-param name="node" select="$node"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:variable name="guidenodes" select="exsl:node-set($guidelinks)/*"/>
+  <xsl:choose>
+    <xsl:when test="count($guidenodes) = 0">
+      <xsl:choose>
+        <xsl:when test="$node/self::mal:section">
+          <xsl:variable name="page" select="$node/ancestor::mal:page"/>
+          <xsl:call-template name="mal.link.linktrails">
+            <xsl:with-param name="node" select="$page"/>
+            <xsl:with-param name="trail">
+              <mal:link xref="{$page/@id}" child="section">
+                <xsl:copy-of select="$page/mal:info/mal:title[ type='sort']"/>
+                <xsl:copy-of select="$trail"/>
+              </mal:link>
+            </xsl:with-param>
+            <xsl:with-param name="root" select="$root"/>
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:copy-of select="$trail"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:for-each select="$guidenodes">
+        <xsl:variable name="self" select="."/>
+        <xsl:choose>
+          <xsl:when test="$self/@xref = $root">
+            <mal:link xref="{$self/@xref}">
+              <xsl:copy-of select="$self/mal:title"/>
+              <xsl:copy-of select="$trail"/>
+            </mal:link>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:for-each select="$mal.cache">
+              <xsl:call-template name="mal.link.linktrails">
+                <xsl:with-param name="node" select="key('mal.cache.key', $self/@xref)"/>
+                <xsl:with-param name="trail">
+                  <mal:link xref="{$self/@xref}">
+                    <xsl:copy-of select="$self/mal:title"/>
+                    <xsl:copy-of select="$trail"/>
+                  </mal:link>
+                </xsl:with-param>
+                <xsl:with-param name="root" select="$root"/>
+              </xsl:call-template>
+            </xsl:for-each>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:for-each>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
 </xsl:stylesheet>
diff --git a/xslt/mallard/html/mal2html-block.xsl b/xslt/mallard/html/mal2html-block.xsl
index 2a67dcc..3ca00ce 100644
--- a/xslt/mallard/html/mal2html-block.xsl
+++ b/xslt/mallard/html/mal2html-block.xsl
@@ -67,6 +67,13 @@ FIXME
 
 <!-- == Matched Templates == -->
 
+<!--%%==========================================================================
+mal2html.block.mode
+FIXME
+
+FIXME
+-->
+
 <!-- = desc = -->
 <xsl:template mode="mal2html.block.mode" match="mal:desc">
   <div class="desc desc-{local-name(..)}">
diff --git a/xslt/mallard/html/mal2html-css.xsl b/xslt/mallard/html/mal2html-css.xsl
index a29d7cf..4179f1d 100644
--- a/xslt/mallard/html/mal2html-css.xsl
+++ b/xslt/mallard/html/mal2html-css.xsl
@@ -107,6 +107,7 @@ body {
 ul, ol, dl, dd { margin: 0; }
 div, pre, p, li, dt { margin: 1em 0 0 0; padding: 0; }
 .first-child { margin-top: 0; }
+li.condensed { margin-top: 0.2em; }
 a {
   text-decoration: none;
   color: </xsl:text>
@@ -118,7 +119,14 @@ a:visited {
 }
 a:hover { text-decoration: underline; }
 
-div.head { margin: 0; }
+div.headbar {
+  margin: 0;
+  max-width: 48em;
+}
+div.footbar {
+  margin: 0;
+  max-width: 48em;
+}
 div.body {
   margin: 0;
   padding: 1em;
@@ -131,7 +139,6 @@ div.body {
     <xsl:value-of select="$theme.color.background"/><xsl:text>;
 }
 div.copyrights {
-  max-width: 48em;
   text-align: center;
   color: </xsl:text>
     <xsl:value-of select="$theme.color.text_light"/><xsl:text>;
@@ -167,6 +174,9 @@ div.autolinks div.title span {
 }
 li.autolink { margin: 0.5em 0 0 0; padding: 0 0 0 1em; list-style-type: none; }
 
+div.linktrails {
+  margin: 0;
+}
 div.linktrail {
   font-size: 0.83em;
   margin: 0 1px 0.2em 1px;
@@ -183,24 +193,24 @@ td.twocolumnright {
   padding-</xsl:text><xsl:value-of select="$left"/><xsl:text>: 1em;
 }
 
-div.pagelink div.title {
+div.linkdiv div.title {
   font-size: 1em;
   color: inherit;
 }
-div.pagelink {
+div.linkdiv {
   margin: 0;
   padding: 0.5em;
   -moz-border-radius: 6px;
   border: solid 1px </xsl:text>
     <xsl:value-of select="$theme.color.background"/><xsl:text>;
 }
-div.pagelink:hover {
+div.linkdiv:hover {
   border-color: </xsl:text>
     <xsl:value-of select="$theme.color.blue_border"/><xsl:text>;
   background-color: </xsl:text>
     <xsl:value-of select="$theme.color.blue_background"/><xsl:text>;
 }
-div.pagelinksep {
+div.linkdivsep {
   margin: 0.5em;
   list-style-type: none;
   max-width: 24em;
@@ -478,7 +488,7 @@ div.version {
 }
 div.version:hover { opacity: 0.8; }
 div.version p.version { margin-top: 0.2em; }
-div.pagelink div.title span.status {
+div.linkdiv div.title span.status {
   font-size: 0.83em;
   font-weight: normal;
   padding-left: 0.2em;
@@ -488,15 +498,15 @@ div.pagelink div.title span.status {
   border: solid 1px </xsl:text>
     <xsl:value-of select="$theme.color.red_border"/><xsl:text>;
 }
-div.pagelink div.title span.status-stub { background-color: </xsl:text>
+div.linkdiv div.title span.status-stub { background-color: </xsl:text>
   <xsl:value-of select="$theme.color.red_background"/><xsl:text>; }
-div.pagelink div.title span.status-draft { background-color: </xsl:text>
+div.linkdiv div.title span.status-draft { background-color: </xsl:text>
   <xsl:value-of select="$theme.color.red_background"/><xsl:text>; }
-div.pagelink div.title span.status-incomplete { background-color: </xsl:text>
+div.linkdiv div.title span.status-incomplete { background-color: </xsl:text>
   <xsl:value-of select="$theme.color.red_background"/><xsl:text>; }
-div.pagelink div.title span.status-review { background-color: </xsl:text>
+div.linkdiv div.title span.status-review { background-color: </xsl:text>
   <xsl:value-of select="$theme.color.yellow_background"/><xsl:text>; }
-div.pagelink div.desc {
+div.linkdiv div.desc {
   margin-top: 0.2em;
   color: </xsl:text>
     <xsl:value-of select="$theme.color.text_light"/><xsl:text>;
diff --git a/xslt/mallard/html/mal2html-inline.xsl b/xslt/mallard/html/mal2html-inline.xsl
index 547402f..7103d61 100644
--- a/xslt/mallard/html/mal2html-inline.xsl
+++ b/xslt/mallard/html/mal2html-inline.xsl
@@ -68,12 +68,12 @@ REMARK: Document this template
         <a>
           <xsl:attribute name="href">
             <xsl:call-template name="mal.link.target">
-              <xsl:with-param name="link" select="$node"/>
+              <xsl:with-param name="node" select="$node"/>
             </xsl:call-template>
           </xsl:attribute>
           <xsl:attribute name="title">
             <xsl:call-template name="mal.link.tooltip">
-              <xsl:with-param name="link" select="$node"/>
+              <xsl:with-param name="node" select="$node"/>
             </xsl:call-template>
           </xsl:attribute>
           <xsl:apply-templates mode="mal2html.inline.content.mode" select="$node"/>
@@ -252,6 +252,11 @@ REMARK: Document this template
   <xsl:text>"</xsl:text>
 </xsl:template>
 
+<!-- = span = -->
+<xsl:template mode="mal2html.inline.mode" match="mal:span">
+  <xsl:call-template name="mal2html.span"/>
+</xsl:template>
+
 <!-- = sys = -->
 <xsl:template mode="mal2html.inline.mode" match="mal:sys">
   <xsl:call-template name="mal2html.span"/>
diff --git a/xslt/mallard/html/mal2html-list.xsl b/xslt/mallard/html/mal2html-list.xsl
index cac1a93..6ec692c 100644
--- a/xslt/mallard/html/mal2html-list.xsl
+++ b/xslt/mallard/html/mal2html-list.xsl
@@ -28,6 +28,31 @@ REMARK: Describe this module
 -->
 
 
+<!--%%==========================================================================
+mal2html.list.list.mode
+FIXME
+
+FIXME
+-->
+<!--%%==========================================================================
+mal2html.list.steps.mode
+FIXME
+
+FIXME
+-->
+<!--%%==========================================================================
+mal2html.list.terms.mode
+FIXME
+
+FIXME
+-->
+<!--%%==========================================================================
+mal2html.list.tree.mode
+FIXME
+
+FIXME
+-->
+
 <!-- = list = -->
 <xsl:template mode="mal2html.block.mode" match="mal:list">
   <xsl:param name="first_child" select="not(preceding-sibling::*)"/>
@@ -75,6 +100,9 @@ REMARK: Describe this module
       <xsl:if test="not(preceding-sibling::mal:item)">
         <xsl:text> first-child</xsl:text>
       </xsl:if>
+      <xsl:if test="contains(concat(' ', ../@style, ' '), ' condensed ')">
+        <xsl:text> condensed</xsl:text>
+      </xsl:if>
     </xsl:attribute>
     <xsl:for-each
      select="mal:*[
diff --git a/xslt/mallard/html/mal2html-media.xsl b/xslt/mallard/html/mal2html-media.xsl
index fb97fc8..66e6ac4 100644
--- a/xslt/mallard/html/mal2html-media.xsl
+++ b/xslt/mallard/html/mal2html-media.xsl
@@ -27,6 +27,87 @@ Mallard to HTML - Media Elements
 REMARK: Describe this module
 -->
 
+<!--**==========================================================================
+mal2html.media.image
+FIXME
+
+FIXME
+-->
+<xsl:template name="mal2html.media.image">
+  <xsl:param name="node" select="."/>
+  <xsl:param name="inline" select="false()"/>
+  <img src="{$node/@src}">
+    <xsl:copy-of select="@height"/>
+    <xsl:copy-of select="@width"/>
+    <xsl:attribute name="alt">
+      <xsl:choose>
+        <xsl:when test="$inline">
+          <xsl:value-of select="$node"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <!-- FIXME: This is not ideal.  Nested block container elements
+               will introduce lots of garbage whitespace.  But then, XML
+               processors are supposed to normalize whitespace in attribute
+               values anyway.  Ideally, we'd have a set of modes for text
+               conversion.  That'd probably be best handled in a set of
+               mal2text stylesheets.
+          -->
+          <xsl:for-each select="$node/mal:*">
+            <xsl:if test="position() &gt; 1">
+              <xsl:text>&#x000A;</xsl:text>
+            </xsl:if>
+            <xsl:value-of select="string(.)"/>
+          </xsl:for-each>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:attribute>
+  </img>
+</xsl:template>
+
+<!--**==========================================================================
+mal2html.media.video
+FIXME
+
+FIXME
+-->
+<xsl:template name="mal2html.media.video">
+  <xsl:param name="node" select="."/>
+  <xsl:param name="inline" select="false()"/>
+  <video src="{$node/@src}" autobuffer="autobuffer" controls="controls">
+    <xsl:copy-of select="$node/@height"/>
+    <xsl:copy-of select="$node/@width"/>
+    <xsl:choose>
+      <xsl:when test="$inline">
+        <xsl:apply-templates mode="mal2html.inline.mode" select="$node/node()"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates mode="mal2html.block.mode" select="$node/node()"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </video>
+</xsl:template>
+
+<!--**==========================================================================
+mal2html.media.audio
+FIXME
+
+FIXME
+-->
+<xsl:template name="mal2html.media.audio">
+  <xsl:param name="node" select="."/>
+  <xsl:param name="inline" select="false()"/>
+  <audio src="{$node/@src}" autobuffer="autobuffer" controls="controls">
+    <xsl:choose>
+      <xsl:when test="$inline">
+        <xsl:apply-templates mode="mal2html.inline.mode" select="$node/node()"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates mode="mal2html.block.mode" select="$node/node()"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </audio>
+</xsl:template>
+
 
 <!-- == Matched Templates == -->
 
@@ -42,30 +123,34 @@ REMARK: Describe this module
             <xsl:text> first-child</xsl:text>
           </xsl:if>
         </xsl:attribute>
-        <img src="{ src}">
-          <xsl:copy-of select="@height"/>
-          <xsl:copy-of select="@width"/>
-          <xsl:attribute name="alt">
-            <!-- FIXME: This is not ideal.  Nested block container elements
-                 will introduce lots of garbage whitespace.  But then, XML
-                 processors are supposed to normalize whitespace in attribute
-                 values anyway.  Ideally, we'd have a set of modes for text
-                 conversion.  That'd probably be best handled in a set of
-                 mal2text stylesheets.
-            -->
-            <xsl:for-each select="mal:*">
-              <xsl:if test="position() &gt; 1">
-                <xsl:text>&#x000A;</xsl:text>
-              </xsl:if>
-              <xsl:value-of select="string(.)"/>
-            </xsl:for-each>
-          </xsl:attribute>
-        </img>
+        <xsl:call-template name="mal2html.media.image"/>
+      </div>
+    </xsl:when>
+    <xsl:when test="@type = 'video'">
+      <div>
+        <xsl:attribute name="class">
+          <xsl:text>media media-video</xsl:text>
+          <xsl:if test="$first_child">
+            <xsl:text> first-child</xsl:text>
+          </xsl:if>
+        </xsl:attribute>
+        <xsl:call-template name="mal2html.media.video"/>
+      </div>
+    </xsl:when>
+    <xsl:when test="@type = 'audio'">
+      <div>
+        <xsl:attribute name="class">
+          <xsl:text>media media-audio</xsl:text>
+          <xsl:if test="$first_child">
+            <xsl:text> first-child</xsl:text>
+          </xsl:if>
+        </xsl:attribute>
+        <xsl:call-template name="mal2html.media.audio"/>
       </div>
     </xsl:when>
     <xsl:otherwise>
       <xsl:for-each select="mal:*">
-        <xsl:apply-templates mode="db2html.block.mode" select=".">
+        <xsl:apply-templates mode="mal2html.block.mode" select=".">
           <xsl:with-param name="first_child" select="position() = 1 and $first_child"/>
         </xsl:apply-templates>
       </xsl:for-each>
@@ -78,17 +163,27 @@ REMARK: Describe this module
   <xsl:choose>
     <xsl:when test="@type = 'image'">
       <span class="media media-image">
-        <img src="{ src}">
-          <xsl:copy-of select="@height"/>
-          <xsl:copy-of select="@width"/>
-          <xsl:attribute name="alt">
-            <xsl:value-of select="."/>
-          </xsl:attribute>
-        </img>
+        <xsl:call-template name="mal2html.media.image">
+          <xsl:with-param name="inline" select="true()"/>
+        </xsl:call-template>
+      </span>
+    </xsl:when>
+    <xsl:when test="@type = 'video'">
+      <span class="media media-video">
+        <xsl:call-template name="mal2html.media.video">
+          <xsl:with-param name="inline" select="true()"/>
+        </xsl:call-template>
+      </span>
+    </xsl:when>
+    <xsl:when test="@type = 'audio'">
+      <span class="media media-audio">
+        <xsl:call-template name="mal2html.media.audio">
+          <xsl:with-param name="inline" select="true()"/>
+        </xsl:call-template>
       </span>
     </xsl:when>
     <xsl:otherwise>
-      <xsl:apply-templates mode="db2html.inline.mode"/>
+      <xsl:apply-templates mode="mal2html.inline.mode"/>
     </xsl:otherwise>
   </xsl:choose>
 </xsl:template>
diff --git a/xslt/mallard/html/mal2html-page.xsl b/xslt/mallard/html/mal2html-page.xsl
index 52a56e1..78c91ed 100644
--- a/xslt/mallard/html/mal2html-page.xsl
+++ b/xslt/mallard/html/mal2html-page.xsl
@@ -19,6 +19,7 @@ Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                 xmlns:mal="http://projectmallard.org/1.0/";
                 xmlns:str="http://exslt.org/strings";
+                xmlns:exsl="http://exslt.org/common";
                 xmlns="http://www.w3.org/1999/xhtml";
                 version="1.0">
 
@@ -29,15 +30,29 @@ REMARK: Describe this module
 -->
 
 
+<!--@@==========================================================================
+mal2html.editor.mode
+Add information that's useful to writers and editors.
+
+When this parameter is set to true, these stylesheets will output editorial
+comments, status markers, and other information that's useful to writers and
+editors.
+-->
 <xsl:param name="mal2html.editor_mode" select="false()"/>
 
 
 <!--**==========================================================================
-mal2html.page.copyright
-Outputs the copyright notice at the bottom of a page
-$node: The top-level #{page} element
+mal2html.page.copyrights
+Output the copyright notice at the bottom of a page.
+:Revision:version="1.0" date="2010-01-02"
+$node: The top-level #{page} element.
 
-REMARK: Describe this template
+This template outputs copyright information.  By default, it is placed at the
+bottom of the page by *{mal2html.page.footbar}.  Copyrights are taken from the
+#{credit} elements in the #{info} element in ${node}.
+
+Copyright information is output in a #{div} element with #{class="copyrights"}.
+Each copyright is output in a nested #{div} element with #{class="copyright"}.
 -->
 <xsl:template name="mal2html.page.copyrights">
   <xsl:param name="node"/>
@@ -53,136 +68,95 @@ REMARK: Describe this template
 
 
 <!--**==========================================================================
-mal2html.page.pagelinks
+mal2html.page.topiclinks
 Outputs the automatic links from a guide page or guide section
 $node: The #{page} or #{section} element containing the links
 
 REMARK: Describe this template
 -->
-<xsl:template name="mal2html.page.pagelinks">
+<xsl:template name="mal2html.page.topiclinks">
   <xsl:param name="node" select="."/>
-  <xsl:variable name="id">
-    <xsl:choose>
-      <xsl:when test="$node/self::mal:section">
-        <xsl:value-of select="concat($node/ancestor::mal:page[1]/@id, '#', $node/@id)"/>
-      </xsl:when>
-      <xsl:otherwise>
-        <xsl:value-of select="$node/@id"/>
-      </xsl:otherwise>
-    </xsl:choose>
+  <xsl:variable name="topiclinks">
+    <xsl:call-template name="mal.link.topiclinks"/>
   </xsl:variable>
-  <xsl:variable name="pagelinks"
-                select="$node/mal:info/mal:link[ type = 'topic']"/>
-  <!-- FIXME: // selectors are slow -->
-  <xsl:variable name="guidelinks"
-                select="$mal.cache//*[mal:info/mal:link[ type = 'guide'][ xref = $id]]
-                                     [not(@id = $pagelinks/@xref)]"/>
-  <xsl:if test="$pagelinks or $guidelinks">
-    <div class="pagelinks">
-      <xsl:choose>
-        <xsl:when test="contains(concat(' ', $node/@style, ' '), ' 2column ')">
-          <xsl:variable name="coltot" select="ceiling(count($pagelinks | $guidelinks) div 2)"/>
-          <table class="twocolumn"><tr>
-            <td class="twocolumnleft">
-              <xsl:for-each select="$pagelinks[position() &lt;= $coltot]">
+  <xsl:variable name="topicnodes" select="exsl:node-set($topiclinks)/*"/>
+  <div class="topiclinks">
+    <xsl:choose>
+      <xsl:when test="contains(concat(' ', $node/@style, ' '), ' 2column ')">
+        <xsl:variable name="coltot" select="ceiling(count($topicnodes) div 2)"/>
+        <table class="twocolumn"><tr>
+          <td class="twocolumnleft">
+            <xsl:for-each select="$topicnodes">
+              <xsl:sort data-type="number" select="@groupsort"/>
+              <xsl:sort select="mal:title[ type = 'sort']"/>
+              <xsl:if test="position() &lt;= $coltot">
                 <xsl:variable name="xref" select="@xref"/>
                 <xsl:for-each select="$mal.cache">
-                  <xsl:call-template name="mal2html.page.pagelink">
+                  <xsl:call-template name="mal2html.page.linkdiv">
                     <xsl:with-param name="source" select="$node"/>
                     <xsl:with-param name="target" select="key('mal.cache.key', $xref)"/>
                   </xsl:call-template>
                 </xsl:for-each>
-              </xsl:for-each>
-              <xsl:for-each select="$guidelinks">
-                <xsl:sort select="mal:info/mal:link[ type = 'guide'][ xref = $id]/@weight"
-                          data-type="number" order="descending"/>
-                <!-- FIXME: lang -->
-                <xsl:sort select="mal:info/mal:title[ type = 'sort']"
-                          data-type="text" order="ascending"/>
-                <xsl:if test="(position() + count($pagelinks)) &lt;= $coltot">
-                  <xsl:call-template name="mal2html.page.pagelink">
-                    <xsl:with-param name="source" select="$node"/>
-                    <xsl:with-param name="target" select="."/>
-                  </xsl:call-template>
-                </xsl:if>
-              </xsl:for-each>
-            </td>
-            <td class="twocolumnright">
-              <xsl:for-each select="$pagelinks[position() &gt; $coltot]">
+              </xsl:if>
+            </xsl:for-each>
+          </td>
+          <td class="twocolumnright">
+            <xsl:for-each select="$topicnodes">
+              <xsl:sort data-type="number" select="@groupsort"/>
+              <xsl:sort select="mal:title[ type = 'sort']"/>
+              <xsl:if test="position() &gt; $coltot">
                 <xsl:variable name="xref" select="@xref"/>
                 <xsl:for-each select="$mal.cache">
-                  <xsl:call-template name="mal2html.page.pagelink">
+                  <xsl:call-template name="mal2html.page.linkdiv">
                     <xsl:with-param name="source" select="$node"/>
                     <xsl:with-param name="target" select="key('mal.cache.key', $xref)"/>
                   </xsl:call-template>
                 </xsl:for-each>
-              </xsl:for-each>
-              <xsl:for-each select="$guidelinks">
-                <xsl:sort select="mal:info/mal:link[ type = 'guide'][ xref = $id]/@weight"
-                          data-type="number" order="descending"/>
-                <!-- FIXME: lang -->
-                <xsl:sort select="mal:info/mal:title[ type = 'sort']"
-                          data-type="text" order="ascending"/>
-                <xsl:if test="(position() + count($pagelinks)) &gt; $coltot">
-                  <xsl:call-template name="mal2html.page.pagelink">
-                    <xsl:with-param name="source" select="$node"/>
-                    <xsl:with-param name="target" select="."/>
-                  </xsl:call-template>
-                </xsl:if>
-              </xsl:for-each>
-            </td>
-          </tr></table>
-        </xsl:when>
-        <xsl:otherwise>
-          <xsl:for-each select="$pagelinks">
-            <xsl:variable name="xref" select="@xref"/>
-            <xsl:for-each select="$mal.cache">
-              <xsl:call-template name="mal2html.page.pagelink">
-                <xsl:with-param name="source" select="$node"/>
-                <xsl:with-param name="target" select="key('mal.cache.key', $xref)"/>
-              </xsl:call-template>
+              </xsl:if>
             </xsl:for-each>
-          </xsl:for-each>
-          <xsl:for-each select="$guidelinks">
-            <xsl:sort select="mal:info/mal:link[ type = 'guide'][ xref = $id]/@weight"
-                      data-type="number" order="descending"/>
-            <!-- FIXME: lang -->
-            <xsl:sort select="mal:info/mal:title[ type = 'sort']"
-                      data-type="text" order="ascending"/>
-            <xsl:call-template name="mal2html.page.pagelink">
+          </td>
+        </tr></table>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:for-each select="$topicnodes">
+          <xsl:sort data-type="number" select="@groupsort"/>
+          <xsl:sort select="mal:title[ type = 'sort']"/>
+          <xsl:variable name="xref" select="@xref"/>
+          <xsl:for-each select="$mal.cache">
+            <xsl:call-template name="mal2html.page.linkdiv">
               <xsl:with-param name="source" select="$node"/>
-              <xsl:with-param name="target" select="."/>
+              <xsl:with-param name="target" select="key('mal.cache.key', $xref)"/>
             </xsl:call-template>
           </xsl:for-each>
-        </xsl:otherwise>
-      </xsl:choose>
-    </div>
-  </xsl:if>
+        </xsl:for-each>
+      </xsl:otherwise>
+    </xsl:choose>
+  </div>
 </xsl:template>
 
 
 <!--**==========================================================================
-mal2html.page.pagelink
+mal2html.page.linkdiv
 Outputs an automatic link block from a guide to a page
 $source: The #{page} or #{section} element containing the link
 $target: The element from the cache file of the page being linked to
 
 REMARK: Describe this template
 -->
-<xsl:template name="mal2html.page.pagelink">
+<xsl:template name="mal2html.page.linkdiv">
   <xsl:param name="source" select="."/>
   <xsl:param name="target"/>
   <a>
     <xsl:attribute name="href">
       <xsl:call-template name="mal.link.target">
-        <xsl:with-param name="link" select="$source"/>
+        <xsl:with-param name="node" select="$source"/>
         <xsl:with-param name="xref" select="$target/@id"/>
       </xsl:call-template>
     </xsl:attribute>
-    <div class="pagelink">
+    <div class="linkdiv">
       <div class="title">
         <xsl:call-template name="mal.link.content">
-          <xsl:with-param name="link" select="$source"/>
+          <xsl:with-param name="node" select="$source"/>
           <xsl:with-param name="xref" select="$target/@id"/>
           <xsl:with-param name="role" select="'topic'"/>
         </xsl:call-template>
@@ -274,11 +248,13 @@ REMARK: Describe this template
                 select="$mal.cache//*[mal:info/mal:link[ type = 'seealso'][ xref = $id]]"/>
   <xsl:variable name="outlinks"
                 select="$node/mal:info/mal:link[ type = 'seealso']"/>
-  <xsl:variable name="pagelinks"
-                select="$mal.cache//*[mal:info/mal:link[ type = 'topic'][ xref = $id]]"/>
-  <xsl:variable name="guidelinks"
-                select="$node/mal:info/mal:link[ type = 'guide']"/>
-  <xsl:if test="$inlinks or $outlinks or $pagelinks or $guidelinks">
+  <xsl:variable name="guidelinks">
+    <xsl:call-template name="mal.link.guidelinks">
+      <xsl:with-param name="node" select="$node"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:variable name="guidenodes" select="exsl:node-set($guidelinks)/*"/>
+  <xsl:if test="$inlinks or $outlinks or $guidenodes">
     <div class="section autolinkssection">
       <div class="header">
         <xsl:element name="{concat('h', $depth)}" namespace="{$mal2html.namespace}">
@@ -292,7 +268,7 @@ REMARK: Describe this template
         </xsl:element>
       </div>
       <div class="autolinks">
-        <xsl:if test="$pagelinks or $guidelinks">
+        <xsl:if test="$guidenodes">
           <div class="title"><span>
             <!-- FIXME: i18n -->
             <xsl:call-template name="l10n.gettext">
@@ -300,14 +276,7 @@ REMARK: Describe this template
             </xsl:call-template>
           </span></div>
           <ul>
-            <xsl:for-each select="$pagelinks">
-              <xsl:call-template name="mal2html.page.autolink">
-                <xsl:with-param name="page" select="."/> 
-                <xsl:with-param name="role" select="'guide'"/>
-             </xsl:call-template>
-            </xsl:for-each>
-            <!-- FIXME: exclude pagelinks -->
-            <xsl:for-each select="$guidelinks">
+            <xsl:for-each select="$guidenodes">
               <xsl:call-template name="mal2html.page.autolink">
                 <xsl:with-param name="xref" select="@xref"/>
                 <xsl:with-param name="role" select="'guide'"/>
@@ -382,6 +351,38 @@ REMARK: Describe this template
 
 
 <!--**==========================================================================
+mal2html.page.headbar
+FIXME
+
+REMARK: FIXME
+-->
+<xsl:template name="mal2html.page.headbar">
+  <xsl:param name="node" select="."/>
+  <div class="headbar">
+    <xsl:call-template name="mal2html.page.linktrails">
+      <xsl:with-param name="node" select="$node"/>
+    </xsl:call-template>
+  </div>
+</xsl:template>
+
+
+<!--**==========================================================================
+mal2html.page.footbar
+FIXME
+
+REMARK: FIXME
+-->
+<xsl:template name="mal2html.page.footbar">
+  <xsl:param name="node" select="."/>
+  <div class="footbar">
+    <xsl:call-template name="mal2html.page.copyrights">
+      <xsl:with-param name="node" select="$node"/>
+    </xsl:call-template>
+  </div>
+</xsl:template>
+
+
+<!--**==========================================================================
 mal2html.page.linktrails
 FIXME
 
@@ -389,101 +390,74 @@ REMARK: Describe this template
 -->
 <xsl:template name="mal2html.page.linktrails">
   <xsl:param name="node" select="."/>
-  <xsl:param name="id">
-    <xsl:choose>
-      <xsl:when test="$node/self::mal:page or contains($node/@id, '#')">
-        <xsl:value-of select="$node/@id"/>
-      </xsl:when>
-      <xsl:otherwise>
-        <xsl:value-of select="$node/ancestor::mal:page/@id"/>
-        <xsl:text>#</xsl:text>
-        <xsl:value-of select="$node/@id"/>
-      </xsl:otherwise>
-    </xsl:choose>
-  </xsl:param>
-  <xsl:param name="trailid" select="$id"/>
-  <xsl:param name="trail" select="''"/>
-  <xsl:variable name="traillist" select="str:split($trail, ':')"/>
-  <xsl:if test="count($traillist) &lt; 5">
-    <xsl:choose>
-      <xsl:when test="$id = 'index'">
-        <xsl:if test="$trail != ''">
-          <xsl:variable name="fulltrail"
-                        select="str:split(concat($trailid, $trail), ':')"/>
-          <div class="linktrail">
-            <xsl:for-each select="$fulltrail">
-              <a class="linktrail">
-                <xsl:attribute name="href">
-                  <xsl:call-template name="mal.link.target">
-                    <xsl:with-param name="xref" select="."/>
-                  </xsl:call-template>
-                </xsl:attribute>
-                <xsl:call-template name="mal.link.content">
-                  <xsl:with-param name="xref" select="."/>
-                  <xsl:with-param name="role" select="'guide'"/>
-                </xsl:call-template>
-              </a>
-              <xsl:text> » </xsl:text>
-            </xsl:for-each>
-          </div>
-        </xsl:if>
-      </xsl:when>
-      <xsl:otherwise>
-        <xsl:variable name="guidelinks"
-                      select="$node/mal:info/mal:link[ type = 'guide']"/>
-        <xsl:variable name="pagelinks"
-                      select="$mal.cache//*[mal:info/mal:link[ type = 'topic'][ xref = $id]]"/>
-        <xsl:if test="not($guidelinks or $pagelinks) and $node/self::mal:section">
-          <xsl:call-template name="mal2html.page.linktrails">
-            <xsl:with-param name="node" select="$node/ancestor::mal:page"/>
-            <xsl:with-param name="trailid" select="$trailid"/>
-            <xsl:with-param name="trail" select="$trail"/>
-          </xsl:call-template>
-        </xsl:if>
-        <xsl:variable name="newtrail">
-          <xsl:choose>
-            <xsl:when test="$trail = ''">
-              <xsl:text>:</xsl:text>
-            </xsl:when>
-            <xsl:otherwise>
-              <xsl:value-of select="concat(':', $trailid, $trail)"/>
-            </xsl:otherwise>
-          </xsl:choose>
-        </xsl:variable>
-        <xsl:for-each select="$guidelinks">
-          <xsl:variable name="fullid">
-            <xsl:choose>
-              <xsl:when test="contains(@xref, '#')">
-                <xsl:variable name="pageid" select="substring-before(@xref, '#')"/>
-                <xsl:variable name="sectionid" select="substring-after(@xref, '#')"/>
-                <xsl:if test="$pageid = ''">
-                  <xsl:value-of select="ancestor::mal:page/@id"/>
-                </xsl:if>
-                <xsl:value-of select="concat($pageid, '#', $sectionid)"/>
-              </xsl:when>
-              <xsl:otherwise>
-                <xsl:value-of select="@xref"/>
-              </xsl:otherwise>
-            </xsl:choose>
-          </xsl:variable>
-          <xsl:for-each select="$mal.cache">
-            <xsl:call-template name="mal2html.page.linktrails">
-              <xsl:with-param name="node" select="key('mal.cache.key', $fullid)"/>
-              <xsl:with-param name="trail" select="$newtrail"/>
-            </xsl:call-template>
-          </xsl:for-each>
-        </xsl:for-each>
-        <xsl:for-each select="$pagelinks">
-          <xsl:call-template name="mal2html.page.linktrails">
-            <xsl:with-param name="node" select="."/>
-            <xsl:with-param name="trail" select="$newtrail"/>
-          </xsl:call-template>
-        </xsl:for-each>
-      </xsl:otherwise>
-    </xsl:choose>
+  <xsl:variable name="linktrails">
+    <xsl:call-template name="mal.link.linktrails">
+      <xsl:with-param name="node" select="$node"/>
+    </xsl:call-template>
+  </xsl:variable>
+  <xsl:variable name="trailnodes" select="exsl:node-set($linktrails)/*"/>
+  <xsl:if test="count($trailnodes) &gt; 0">
+    <div class="linktrails">
+      <xsl:for-each select="$trailnodes">
+        <xsl:sort select="(.//mal:title[ type='sort'])[1]"/>
+        <xsl:sort select="(.//mal:title[ type='sort'])[2]"/>
+        <xsl:sort select="(.//mal:title[ type='sort'])[3]"/>
+        <xsl:sort select="(.//mal:title[ type='sort'])[4]"/>
+        <xsl:sort select="(.//mal:title[ type='sort'])[5]"/>
+        <xsl:call-template name="mal2html.page.linktrails.trail"/>
+      </xsl:for-each>
+    </div>
   </xsl:if>
 </xsl:template>
 
+<!--**==========================================================================
+mal2html.page.linktrails.trail
+FIXME
+
+REMARK: Describe this template
+-->
+<xsl:template name="mal2html.page.linktrails.trail">
+  <xsl:param name="node" select="."/>
+  <div class="linktrail">
+    <xsl:call-template name="mal2html.page.linktrails.link">
+      <xsl:with-param name="node" select="$node"/>
+    </xsl:call-template>
+  </div>
+</xsl:template>
+
+<!--**==========================================================================
+mal2html.page.linktrails.link
+FIXME
+
+REMARK: Describe this template
+-->
+<xsl:template name="mal2html.page.linktrails.link">
+  <xsl:param name="node" select="."/>
+  <a class="linktrail">
+    <xsl:attribute name="href">
+      <xsl:call-template name="mal.link.target">
+        <xsl:with-param name="xref" select="$node/@xref"/>
+      </xsl:call-template>
+    </xsl:attribute>
+    <xsl:call-template name="mal.link.content">
+      <xsl:with-param name="node" select="$node"/>
+      <xsl:with-param name="xref" select="$node/@xref"/>
+      <xsl:with-param name="role" select="'guide'"/>
+    </xsl:call-template>
+  </a>
+  <xsl:choose>
+    <xsl:when test="$node/@child = 'section'">
+      <xsl:text> â?º </xsl:text>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:text> » </xsl:text>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:for-each select="$node/mal:link">
+    <xsl:call-template name="mal2html.page.linktrails.link"/>
+  </xsl:for-each>
+</xsl:template>
+
 
 <!-- == Matched Templates == -->
 
@@ -521,12 +495,10 @@ REMARK: Describe this template
       </title>
       <xsl:call-template name="mal2html.css"/>
     </head>
-    <body>
-      <div class="head">
-        <xsl:call-template name="mal2html.page.linktrails">
-          <xsl:with-param name="node" select="."/>
-        </xsl:call-template>
-      </div>
+    <body class="{ style}">
+      <xsl:call-template name="mal2html.page.headbar">
+        <xsl:with-param name="node" select="."/>
+      </xsl:call-template>
       <div class="body">
         <xsl:if test="$mal2html.editor_mode and $revision/@status != ''">
           <div class="version">
@@ -572,7 +544,7 @@ REMARK: Describe this template
         </xsl:if>
         <xsl:apply-templates select="."/>
       </div>
-      <xsl:call-template name="mal2html.page.copyrights">
+      <xsl:call-template name="mal2html.page.footbar">
         <xsl:with-param name="node" select="."/>
       </xsl:call-template>
     </body>
@@ -595,7 +567,7 @@ REMARK: Describe this template
       </xsl:apply-templates>
     </xsl:for-each>
     <xsl:if test="@type = 'guide'">
-      <xsl:call-template name="mal2html.page.pagelinks"/>
+      <xsl:call-template name="mal2html.page.topiclinks"/>
     </xsl:if>
   </div>
   <xsl:apply-templates select="mal:section"/>
@@ -621,7 +593,7 @@ REMARK: Describe this template
         </xsl:apply-templates>
       </xsl:for-each>
       <xsl:if test="/mal:page/@type = 'guide'">
-        <xsl:call-template name="mal2html.page.pagelinks"/>
+        <xsl:call-template name="mal2html.page.topiclinks"/>
       </xsl:if>
     </div>
     <xsl:apply-templates select="mal:section"/>
@@ -631,6 +603,13 @@ REMARK: Describe this template
   </div>
 </xsl:template>
 
+
+<!--%%==========================================================================
+mal2html.title.mode
+FIXME
+
+FIXE
+-->
 <!-- = subtitle = -->
 <xsl:template mode="mal2html.title.mode" match="mal:subtitle">
   <!-- FIXME -->



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]