<?xml version="1.0" encoding="utf-8"?>
<!-- rss.xsl · In the Gesture SSG
     Writes xml/rss.xml: an RSS 2.0 feed of the ten most recent gestures,
     each carrying its full content as HTML with absolute URLs, so images
     and toward-links resolve in any feed reader. -->
<xsl:stylesheet version="3.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:ig="https://inthegesture.art/ns"
    exclude-result-prefixes="xs ig"
    expand-text="yes">

  <xsl:import href="common.xsl"/>

  <xsl:param name="feed-size" as="xs:integer" select="10"/>

  <!-- ===================== RFC 822 dates ===================== -->
  <!-- Each gesture time carries its own offset, which is written as-is.
       Weekday and month names are spelled out here rather than left to
       format-dateTime, so every processor writes them identically. -->

  <!-- Day of week, 0 = Sunday (1970-01-04 was a Sunday) -->
  <xsl:function name="ig:dow" as="xs:integer">
    <xsl:param name="d" as="xs:date"/>
    <xsl:sequence select="xs:integer(($d - xs:date('1970-01-04'))
                                     div xs:dayTimeDuration('P1D')) mod 7"/>
  </xsl:function>

  <!-- An xs:dateTime's offset in RFC 822 form: -04:00 → -0400, Z → +0000 -->
  <xsl:function name="ig:rfc822-zone" as="xs:string">
    <xsl:param name="dt" as="xs:dateTime"/>
    <xsl:variable name="m" select="xs:integer(
        timezone-from-dateTime($dt) div xs:dayTimeDuration('PT1M'))"/>
    <xsl:sequence select="(if ($m lt 0) then '-' else '+')
        || format-number(abs($m) idiv 60, '00')
        || format-number(abs($m) mod 60, '00')"/>
  </xsl:function>

  <!-- e.g. Fri, 12 Jun 2026 09:55:00 -0400 -->
  <xsl:function name="ig:rfc822" as="xs:string">
    <xsl:param name="dt" as="xs:dateTime"/>
    <xsl:sequence select="
      ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')[ig:dow(xs:date(adjust-dateTime-to-timezone($dt, ()))) + 1]
      || ', ' || format-dateTime($dt, '[D01] ')
      || ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
          'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')[month-from-dateTime($dt)]
      || format-dateTime($dt, ' [Y0001] [H01]:[m01]:[s01] ')
      || ig:rfc822-zone($dt)"/>
  </xsl:function>

  <!-- ===================== the feed ===================== -->

  <xsl:template match="/gestures">
    <xsl:variable name="newest-first" as="element(gesture)*">
      <xsl:perform-sort select="gesture">
        <xsl:sort select="ig:dt(time)" order="descending"/>
      </xsl:perform-sort>
    </xsl:variable>
    <xsl:variable name="items" select="$newest-first[position() le $feed-size]"/>

    <xsl:result-document href="xml/rss.xml" method="xml" indent="yes" encoding="utf-8">
      <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
        <channel>
          <title>In the Gesture</title>
          <link>{$site}</link>
          <description>{$site-description}</description>
          <language>en-us</language>
          <!-- the newest gesture's time, so an unchanged log
               rebuilds to a byte-identical feed -->
          <xsl:if test="exists($items)">
            <lastBuildDate>{ig:rfc822(ig:dt($items[1]/time))}</lastBuildDate>
          </xsl:if>
          <atom:link href="{$site}xml/rss.xml" rel="self" type="application/rss+xml"/>

          <xsl:for-each select="$items">
            <xsl:variable name="url" select="$site || 'g/' || ig:slug(time) || '.html'"/>
            <xsl:variable name="content" as="node()*">
              <xsl:apply-templates select="." mode="feed"/>
            </xsl:variable>
            <item>
              <title>{ig:when(time)}</title>
              <link>{$url}</link>
              <guid isPermaLink="true">{$url}</guid>
              <pubDate>{ig:rfc822(ig:dt(time))}</pubDate>
              <description>{serialize($content,
                  map{'method': 'html', 'html-version': 5.0, 'indent': false()})}</description>
            </item>
          </xsl:for-each>
        </channel>
      </rss>
    </xsl:result-document>
  </xsl:template>

  <!-- An item's HTML: the gesture page's article body, with the site
       root as an absolute $root so every src and href resolves in a
       reader. Kept outside the <rss> literal so the Atom namespace
       declared there doesn't ride along onto these elements. -->
  <xsl:template match="gesture" mode="feed">
    <p class="place">{place}</p>
    <xsl:apply-templates select="* except (time, place)" mode="render">
      <xsl:with-param name="root" select="$site" tunnel="yes"/>
    </xsl:apply-templates>
  </xsl:template>

</xsl:stylesheet>
