<?xml version="1.0" encoding="iso-8859-1"?><?emacs -*- mode: XML; coding: iso-8859-1 -*- ?> 
<xsl:stylesheet
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xalan="http://xml.apache.org/xalan"
  xmlns:dt="http://exslt.org/dates-and-times"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:rss1="http://purl.org/rss/1.0/"
  exclude-result-prefixes="xalan dt rdf dc rss1"
  version="1.0">

  <xsl:output method="xml"
    version="1.0"
    doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
    indent="yes"
    encoding="iso-8859-1"
    xalan:indent-amount="2"/>

  <xsl:param name="sourcefile" />

  <xsl:strip-space elements="group item"/>

  <!-- Document outline.  This provides the overall structure -->

  <xsl:template match="/">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
      <head>
        <xsl:apply-templates mode="header" />
        <script type="text/javascript">
          function toggleElement(id)  {
              var ele = document.getElementById(id);
              if (ele.style.display == "none") {
                  ele.style.display = "";
              }
              else {
                  ele.style.display = "none";
              }
          }
        </script>
      </head>
      <body>
        <xsl:apply-templates />
        <p class="aboutpage">
          <xsl:text>This page generated</xsl:text>
          <xsl:if test="$sourcefile">
            <xsl:text> from </xsl:text>
            <a href="{$sourcefile}">
              <xsl:value-of select="$sourcefile"/>
            </a>
          </xsl:if>
          <xsl:text> using </xsl:text>
          <a href="http://xml.apache.org/xalan-j/index.html">
            <xsl:text>Xalan-Java 2</xsl:text>
          </a>
          <xsl:text> and </xsl:text>
          <a href="http://www.ste-marie.net/news-links.xsl">
            <xsl:text>news-links.xsl</xsl:text>
          </a>
          <xsl:text> at </xsl:text>
          <xsl:value-of select="dt:dateTime()"/>
          <xsl:text>.</xsl:text>
        </p>
      </body>
    </html>
  </xsl:template>

  <!-- header templates -->

  <xsl:template match="portalpage" mode="header">
    <xsl:apply-templates mode="header"/>
  </xsl:template>

  <xsl:template match="name" mode="header">
    <title><xsl:value-of select="text()" /></title>
  </xsl:template>

  <xsl:template match="refresh" mode="header">
    <meta http-equiv="Refresh" content="{text()}" />
  </xsl:template>

  <xsl:template match="stylesheet[@default = 'yes']" mode="header">
    <link rel="stylesheet" type="text/css" media="{@medium}"
          title="{name}" href="{link}" />
  </xsl:template>

  <xsl:template match="stylesheet[@default = 'no']" mode="header">
    <link rel="alternate stylesheet" type="text/css" media="{@medium}"
          title="{name}" href="{link}" />
  </xsl:template>

  <xsl:template match="navigation" mode="header">
    <link rel="{@rel}" title="{name}" href="{link}" />
  </xsl:template>

  <xsl:template match="stylesheet/name|navigation/name" mode="header">
    <xsl:attribute name="title">
      <xsl:value-of select="text()"/>
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="stylesheet/link|navigation/link" mode="header">
    <xsl:attribute name="href">
      <xsl:value-of select="text()"/>
    </xsl:attribute>
  </xsl:template>

  <!--
     This prevents unmatched items from being processed by the
      default rules.
  -->
  <xsl:template match="*|text()" mode="header" />

  <!-- body templates -->

  <xsl:template match="/portalpage/name">
    <h1><xsl:apply-templates /></h1>
  </xsl:template>

  <!-- These items appear only in the header -->
  <xsl:template match="refresh" />
  <xsl:template match="stylesheet" />
  <xsl:template match="navigation" />

  <!-- Groups containing only items are shortcut groups. -->
  <xsl:template match="/portalpage/group[not(group)]">
    <div class="shortcut">
      <b><xsl:value-of select="translate(name, ' ', '&#160;')"/>:</b>
      <xsl:text> </xsl:text>
      <xsl:apply-templates select="item"/>
    </div>
  </xsl:template>

  <!-- Outer group containing feeds -->
  <xsl:template match="group[group/group/item[rss-feed|meerkat-feed]]">
    <h2 class="feedgroup"><xsl:value-of select="name"/></h2>
    <table>
      <tbody>
        <tr>
          <xsl:apply-templates select="name/following-sibling::*"/>
        </tr>
      </tbody>
    </table>
  </xsl:template>

  <!-- Columns of feeds - this is the second level -->
  <xsl:template match="group/group[group/item[rss-feed|meerkat-feed]]">
    <xsl:variable name="columnwidth">
      <xsl:value-of select="string(round(100 div count(../group)))"/>
      <xsl:text>%</xsl:text>
    </xsl:variable>
    <td valign="top" style="width: {$columnwidth}">
      <xsl:apply-templates />
    </td>
  </xsl:template>

  <!-- Blocks of feeds - this is the third level -->
  <xsl:template match="group[group/item[rss-feed|meerkat-feed]
                                        and not(name(..) = 'group')]">
    <h2 class="feedgroup"><xsl:value-of select="name"/></h2>
    <xsl:apply-templates select="name/following-sibling::*"/>
  </xsl:template>

  <!-- Group of feeds - this is the fourth and final level -->
  <xsl:template match="group[item[rss-feed|meerkat-feed]]">
    <h3 class="feedgroup"><xsl:value-of select="name"/></h3>
    <xsl:apply-templates select="item"/>
  </xsl:template>

  <!-- Item with name and feed(s). -->
  <xsl:template match="item[name and (meerkat-feed or rss-feed)]">
    <div class="feedheader">
      <h4><xsl:apply-templates select="name"/></h4>
    </div>
    <xsl:apply-templates select="*[name() != 'name']"/>
  </xsl:template>

  <!-- Second and subsequent shortcut items -->
  <xsl:template match="/portalpage/group[not(group)]/item[position() &gt; 1]">
    <xsl:text disable-output-escaping="yes"> |&amp;nbsp;</xsl:text>
    <xsl:apply-templates />
  </xsl:template>

  <!-- Rawhtml item -->
  <xsl:template match="item[rawhtml]">
    <hr/>
    <xsl:apply-templates/>
    <hr/>
  </xsl:template>

  <!-- primitives -->
  <xsl:template match="rawhtml">
    <xsl:value-of disable-output-escaping="yes" select="."/>
  </xsl:template>

  <xsl:template match="name[following-sibling::link]">
    <a href="{following-sibling::link}"><xsl:apply-templates /></a>
  </xsl:template>

  <!-- links are handled by name rule -->
  <xsl:template match="link"/>

  <!-- General rules for common feed items, e.g. Dublin metadata -->

  <xsl:template match="rss/channel/image|rss1:image">
    <a href="{link|rss1:link}">
      <img src="{url|rss1:url}" alt="{title|rss1:title}"/>
    </a>
  </xsl:template>

  <xsl:template match="rss/channel/title|rss1:channel/rss1:title">
    <xsl:param name="headerlevel" select="h4"/>
    <xsl:element name="{$headerlevel}">
      <xsl:choose>
	<xsl:when test="../link|../rss1:link">
	  <a href="{../link|../rss1:link}"><xsl:value-of select="text()"
                                           disable-output-escaping="yes"/></a>
	</xsl:when>
	<xsl:otherwise>
	  <xsl:value-of select="text()"/>
	</xsl:otherwise>
      </xsl:choose>
    </xsl:element>
  </xsl:template>

  <xsl:template match="story|channel/item|rss1:item">
    <xsl:param name="description" select="'yes'"/>
    <div class="item">
      <xsl:apply-templates select="link|rss1:link"/>
      <xsl:if test="$description = 'yes'">
	<xsl:apply-templates select="description[text()]
	                               | rss1:description[text()]" />
      </xsl:if>
      <xsl:if test="category | dc:subject
                    | channel | dc:creator
                    | timestamp | pubDate | dc:date">
        <div class="publicationInfo">
          <xsl:apply-templates select="category | dc:subject" />
          <xsl:apply-templates select="channel | dc:creator" />
          <xsl:apply-templates select="timestamp | pubDate | dc:date" />
        </div>
      </xsl:if>
    </div>
  </xsl:template>

  <!-- Meerkat is double-escaping ambersands in its links, need to
       compenstate for that here. -->
  <xsl:template match="story/link">
    <xsl:element name="a">
      <xsl:attribute name="href">
	<xsl:call-template name="strip-ampersand-escapes">
	  <xsl:with-param name="text" select="text()"/>
	</xsl:call-template>
      </xsl:attribute>
      <xsl:apply-templates select="../title"/>
    </xsl:element>
  </xsl:template>

  <xsl:template name="strip-ampersand-escapes">
    <xsl:param name="text"/>
    <xsl:choose>
      <xsl:when test="contains($text, '&amp;amp;')">
	<xsl:value-of select="substring-before($text, '&amp;amp;')"/>
	<xsl:text>&amp;</xsl:text>
	<xsl:call-template name="strip-ampersand-escapes">
	  <xsl:with-param name="text"
                       select="substring-after($text, '&amp;amp;')"/>
	</xsl:call-template>
      </xsl:when>
      <xsl:otherwise><xsl:value-of select="$text"/></xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- These are the easy cases where no tweaking of the attribute
       value is required. -->
  <xsl:template match="channel/item/link | rss1:item/rss1:link">
    <a href="{text()}">
      <xsl:apply-templates select="../title | ../rss1:title"/>
    </a>
  </xsl:template>

  <xsl:template match="title | rss1:title">
    <span class="title"><xsl:value-of select="text()"
	disable-output-escaping="yes"/></span>
  </xsl:template>

  <xsl:template match="description | rss1:description">
    <img src="images/toggle.gif" style="vertical-align: baseline"
         alt="toggle description"
         onclick="{concat('toggleElement(&quot;', generate-id(),
                          '&quot;);return true')}"/>
    <div id="{generate-id()}" style="display:none">
      <span class="description">
        <xsl:value-of disable-output-escaping="yes" select="."/>
      </span>
    </div>
  </xsl:template>

  <xsl:template match="category | dc:subject">
    <span class="subject">
      <xsl:apply-templates />
      <xsl:apply-templates mode="punctuate" select="following-sibling::*[1]" />
    </span>
  </xsl:template>

  <xsl:template match="channel | author | dc:creator" mode="punctuate">
    <xsl:text>: </xsl:text>
  </xsl:template>

  <xsl:template match="timestamp | lastBuildDate
                       | pubDate | dc:date" mode="punctuate">
    <xsl:text>, </xsl:text>
  </xsl:template>

  <xsl:template match="channel | author | dc:creator">
    <span class="creator">
      <xsl:apply-templates />
      <xsl:apply-templates mode="punctuate" select="following-sibling::*[1]" />
    </span>
  </xsl:template>

  <xsl:template match="timestamp | lastBuildDate | pubDate | dc:date">
    <span class="date"><xsl:apply-templates /></span>
  </xsl:template>

  <!-- suppress all other items for punctuation -->
  <xsl:template match="*|text()" mode="punctuate"/>

  <!-- RSS templates -->
  <xsl:template match="rss-feed">
    <xsl:variable name="rssurl">
      <xsl:value-of select="text()"/>
    </xsl:variable>
    <xsl:variable name="headerlevel">
      <xsl:choose>
        <xsl:when test="count(../rss-feed) &lt; 2">h4</xsl:when>
        <xsl:otherwise>h5</xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:message terminate="no">
      <xsl:text>Loading </xsl:text>
      <xsl:value-of select="$rssurl"/>
    </xsl:message>
    <xsl:apply-templates select="document($rssurl)/rss/channel
                                 | document($rssurl)/rdf:RDF/rss1:channel">
      <xsl:with-param name="title"      select="@title"/>
      <xsl:with-param name="image"      select="@image"/>
      <xsl:with-param name="description" select="@description"/>
      <xsl:with-param name="item-limit" select="@item-limit"/>
      <xsl:with-param name="feedurl"    select="$rssurl"/>
      <xsl:with-param name="headerlevel" select="$headerlevel"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="rss/channel|rdf:RDF/rss1:channel">
    <xsl:param name="title"      select="'yes'"/>
    <xsl:param name="image"      select="'yes'"/>
    <xsl:param name="description" select="'yes'"/>
    <xsl:param name="item-limit" select="10"/>
    <xsl:param name="feedurl"/>
    <xsl:param name="headerlevel" select="h4"/>
    <div class="feedheader">
      <xsl:apply-templates select="image[$image = 'yes']
	                           | ../rss1:image[$image = 'yes']"/>
      <div class="feedlink">
        <a href="{$feedurl}">
          <img src="images/rss-feed.png" alt="RSS feed"/>
        </a>
      </div>
      <xsl:apply-templates select="title[$title = 'yes']
	                           | rss1:title[$title = 'yes']">
	<xsl:with-param name="headerlevel" select="$headerlevel"/>
      </xsl:apply-templates> 
      <xsl:if test="lastBuildDate | dc:date">
        <div class="publicationInfo">
          <xsl:apply-templates select="lastBuildDate | dc:date"/>
        </div>
      </xsl:if>
    </div>
    <xsl:apply-templates select="item[position() &lt;= number($item-limit)]
                       | ../rss1:item[position() &lt;= number($item-limit)]">
      <xsl:with-param name="description" select="$description"/>
    </xsl:apply-templates>
  </xsl:template>

  <!-- Meerkat templates -->
  <xsl:template match="meerkat-feed">
    <xsl:variable name="meerkaturl">
      <xsl:text>http://meerkat.oreillynet.com/?_fl=xml</xsl:text>
      <xsl:if test="search">
        <xsl:text>&amp;s=</xsl:text><xsl:value-of select="search"/>
      </xsl:if>
      <xsl:if test="search-what">
        <xsl:text>&amp;sw=</xsl:text><xsl:value-of select="search-what"/>
      </xsl:if>
      <xsl:if test="channel">
        <xsl:text>&amp;c=</xsl:text><xsl:value-of select="channel"/>
      </xsl:if>
      <xsl:if test="time-period">
        <xsl:text>&amp;t=</xsl:text><xsl:value-of select="time-period"/>
      </xsl:if>
      <xsl:if test="profile">
        <xsl:text>&amp;p=</xsl:text><xsl:value-of select="profile"/>
      </xsl:if>
      <xsl:if test="mob">
        <xsl:text>&amp;m=</xsl:text><xsl:value-of select="mob"/>
      </xsl:if>
      <xsl:if test="story-id">
        <xsl:text>&amp;i=</xsl:text><xsl:value-of select="story-id"/>
      </xsl:if>
    </xsl:variable>
    <xsl:message terminate="no">
      <xsl:text>Loading </xsl:text>
      <xsl:value-of select="$meerkaturl"/>
    </xsl:message>
    <xsl:apply-templates select="document($meerkaturl)/meerkat">
      <xsl:with-param name="description" select="@description"/>
      <xsl:with-param name="item-limit" select="@item-limit"/>
      <xsl:with-param name="feedurl" select="$meerkaturl"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="meerkat">
    <xsl:param name="description" select="'yes'"/>
    <xsl:param name="item-limit" select="10"/>
    <xsl:param name="feedurl"/>
    <div class="feedlink">
      <a href="{$feedurl}">
        <img src="images/meerkat-feed.png" alt="Meerkat feed"/>
      </a>
    </div>
    <xsl:apply-templates select="story[position() &lt;= number($item-limit)]">
      <xsl:with-param name="description" select="$description"/>
    </xsl:apply-templates>
  </xsl:template>

</xsl:stylesheet>

