<?xml version="1.0"?>
<!--Stylesheet for converting bird notes to HTML.
 !    $Revision: 1.27 $  $Date: 2007/11/30 02:51:00 $
 !  See birdnotes.rnc for the RNC schema for notes.
 !-->

<xsl:stylesheet version="1.0"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!--Generate XHTML 1.0 Strict, and add a DOCTYPE to make the
 !  W3C validator happy.
 !-->
<xsl:output method="xml" encoding="ISO-8859-1" indent="yes"
    doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>

<!--================================================================-->
<!--   < n o t e - s e t >   -->

<!--The root element is note-set.  Its period attribute gives
 !  the time period, e.g., "June 2004".
 !-->
<xsl:template match="note-set">
  <xsl:variable name="title">
    <xsl:text>Shipman's field notes, </xsl:text>
    <xsl:value-of select="@period"/>
  </xsl:variable>
  <html>
  <head>
    <title>
      <xsl:value-of select="$title"/>
    </title>
    <link rel="stylesheet"
          href="http://www.nmt.edu/~shipman/aba/birdnotes.css"/>
  </head>
  <body>
    <h1>
      <xsl:value-of select="$title"/>
    </h1>

    <!--Output the page's table of contents, a bullet list with
     !  links to each day.
     !-->
    <xsl:call-template name='page-toc'/>

    <p>
      <a href="http://www.nmt.edu/~shipman/aba/conventions.html"
      >How to read Shipman's field notes</a>
    </p>

    <!--Output each daily note set.
     !-->
    <xsl:apply-templates select="day-notes"/>
  </body>
  </html>
</xsl:template>

<!--================================================================-->
<!--   p a g e - t o c   -->

<xsl:template name='page-toc'>
  <ul>
    <xsl:apply-templates select="day-notes" mode="toc"/>
  </ul>
</xsl:template>

<!--================================================================-->
<!--   < d a y - n o t e s >  mode="toc"   -->

<xsl:template match='day-notes' mode='toc'>
  <li>
    <a href="{concat('#', @date)}">
      <xsl:call-template name='day-title'/>
    </a>
    <!--Using the 'notables' mode, process the list of forms to
     !  extract all the notable records.
     !-->
    <xsl:apply-templates mode="notables" select="."/>
  </li>
</xsl:template>


<!--================================================================-->
<!--   < d a y - n o t e s >   -->

<!--day-notes is the container for one day's worth of notes.
 !  It has a required day-summary child, then zero or more
 !  form elements that record sightings of kinds of birds.
 !-->
<xsl:template match="day-notes">
  <hr/>

  <!--Generate a heading for the day.
   !-->
  <h2>
    <a name="{@date}">
      <xsl:call-template name='day-title'/>
    </a>
  </h2>

  <div class="day-summary">
    <!--Using the 'notables' mode, process the list of forms to
     !  extract all the notable records.
     !-->
    <xsl:apply-templates mode="notables" select="."/>

    <!--Process the daily summary data.  !-->
    <xsl:apply-templates select="day-summary"/>
  </div>
  <xsl:apply-templates select="form"/>
</xsl:template>


<!--================================================================-->
<!--   d a y - t i t l e   -->

<!--[ "." is a day-notes element ->
 !      output (upshifted state name) + ": " + (date) + ": " +
 !        (today's location text) ]
 !-->
<xsl:template name='day-title'>
  <!--[ output (upshifted state name) + ": " + (date) + ": " ]-->
  <xsl:value-of select="translate(@state,
                'abcdefghijklmnopqrstuvwxyz',
                'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
  <xsl:text>: </xsl:text>
  <xsl:value-of select="@date"/>
  <xsl:text>: </xsl:text>

  <!--[ output today's location text ]-->
  <xsl:call-template name='day-loc-text'/>
</xsl:template>

<!--================================================================-->
<!--   d a y - l o c - t e x t   -->

<!--[ "." is a day-notes element ->
 !      if "." has a @day-loc attribute ->
 !        output text of day-summary/loc element whose @code
 !        matches @day-loc
 !      else ->
 !        output text of day-summary/loc element whose @code
 !        matches day-summary/@default-loc ]
 !-->
<xsl:template name='day-loc-text'>
  <xsl:choose>
    <xsl:when test="@day-loc">
      <xsl:call-template name='loc-text'>
        <xsl:with-param name='loc-code' select='@day-loc'/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name='loc-text'>
        <xsl:with-param name='loc-code'
                        select='day-summary/@default-loc'/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!--================================================================-->
<!--   l o c - t e x t   -->

<!--[ ("." is a day-notes element) and
 !    ($loc-code is a location code) ->
 !      if there is a day-summary/loc element whose @code matches
 !      $loc-code ->
 !        output the name from that element
 !      else ->
 !        stderr  +:=  error message
 !-->
<xsl:template name='loc-text'>
  <xsl:param name='loc-code'/>

  <xsl:variable name='loc-name'>
    <xsl:value-of select='day-summary/loc[@code = $loc-code]/@name'/>
  </xsl:variable>
  <xsl:if test="$loc-name = ''">
    <xsl:message
    >*** Unknown location code (<xsl:value-of select='$loc-code'/>)
    </xsl:message>
  </xsl:if>
  <xsl:value-of select='$loc-name'/>
</xsl:template>


<!--================================================================-->
<!--   < d a y - s u m m a r y >   -->

<!--day-summary is a container for information about the field day.
 !-->
<xsl:template match="day-summary">

  <!--Give the default location for today's records.
   !-->
  <xsl:call-template name="default-loc">
    <xsl:with-param name="loc" select="@default-loc"/>
  </xsl:call-template>

  <!--Display all loc elements, defining today's location codes.
   !-->
  <xsl:apply-templates select="loc"/>

  <!--Display any elements in the day-annotation pattern.
   !-->
  <xsl:apply-templates select="route|weather|missed|film"/>

  <!--Other text is either structured into <para> elements
   !  or plain text children of day-summary.
   !-->
  <xsl:apply-templates select="para"/>

  <!--Output a div.narrative only if there are text children.
   !-->
  <xsl:variable name="narrative">
    <xsl:call-template name="find-text">
      <xsl:with-param name="node" select="."/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:if test="normalize-space($narrative) != ''">
    <div class="loc-narrative">
      <xsl:value-of select="$narrative"/>
    </div>
  </xsl:if>
</xsl:template>


<!--================================================================-->
<!--   f i n d - t e x t   -->

<!--[ $node is an element node ->                                               
 !      return the concatenation of all text children of $node,                 
 !      with spaces normalized ]                                                
 !-->
<xsl:template name="find-text">
  <xsl:param name="node"/>

  <xsl:variable name="result">
    <xsl:for-each select="$node/text()">
      <!--[ "." is a text node ->                                               
       !      output "." with spaces normalized ]                               
       !-->
      <xsl:value-of select="."/>
    </xsl:for-each>
  </xsl:variable>
  <xsl:value-of select="normalize-space($result)"/>
</xsl:template>


<!--================================================================-->
<!--   d e f a u l t - l o c   -->

<!--default-loc formats the default location.  It takes one argument,
 !  loc, containing the default location code.
 !-->
<xsl:template name="default-loc">
  <xsl:param name="loc">None</xsl:param>
  <div class="loc-child">
    <span class="loc-label">
      <xsl:text>Default location: @</xsl:text>
    </span>
    <xsl:value-of select="$loc"/>
  </div>
</xsl:template>

<!--================================================================-->
<!--   < l o c >   -->

<!--Process the loc element, which defines one location code.
 !-->
<xsl:template match="loc">
  <div class="loc-def">
    <xsl:text>@</xsl:text>
    <xsl:value-of select="@code"/>
    <xsl:text>: </xsl:text>
    <xsl:value-of select="@name"/>
    <xsl:if test="text()">
      <div class="loc-narrative">
        <!--See the template for day-summary for comments on why
         !  it doesn't work to say <xsl:value-of select="text()"/>.
         !-->
        <xsl:for-each select='text()'>
          <xsl:value-of select="."/>
        </xsl:for-each>
      </div>
    </xsl:if>
    <xsl:apply-templates select="gps"/>
  </div>
</xsl:template>

<!--================================================================-->
<!--   < g p s >   -->

<!--The gps element is a child of loc, and gives GPS coordinates.
 !  The waypoint attribute is required; text is optional.
 !-->
<xsl:template match="gps">
  <div class="loc-narrative">
    <xsl:text>GPS: </xsl:text>
    <xsl:value-of select="@waypoint"/>
    <xsl:if test="text()">
      <xsl:value-of select="text()"/>
    </xsl:if>
  </div>
</xsl:template>

<!--================================================================-->
<!--   < r o u t e >   -->

<!--The route element shows the route taken.
 !-->
<xsl:template match="route">
  <xsl:call-template name="loc-child">
    <xsl:with-param name="label" select="'Route'"/>
  </xsl:call-template>
</xsl:template>

<!--================================================================-->
<!--   l o c - c h i l d   -->

<!--loc-child: This named template is used to format blocks such
 !  as weather, film, etc.; the label argument contains the
 !  descriptive label such as "Weather", and the context node's
 !  text children are displayed after that label.
 !-->
<xsl:template name="loc-child">
  <xsl:param name="label"/>
  <div class="loc-child">
    <span class="loc-label">
      <xsl:value-of select="$label"/>
      <xsl:text>: </xsl:text>
    </span>
<!--
    <xsl:value-of select="text()"/>
-->
    <xsl:apply-templates/>
  </div>
</xsl:template>

<!--================================================================-->
<!--   < w e a t h e r >   -->

<!--The weather element describes the weather.
 !-->
<xsl:template match="weather">
  <xsl:call-template name="loc-child">
    <xsl:with-param name="label" select="'Weather'"/>
  </xsl:call-template>
</xsl:template>

<!--================================================================-->
<!--   < m i s s e d >   -->

<!--The missed element mentions expected forms not seen.
 !-->
<xsl:template match="missed">
  <xsl:call-template name="loc-child">
    <xsl:with-param name="label" select="'Missed'"/>
  </xsl:call-template>
</xsl:template>

<!--================================================================-->
<!--   < f i l m >   -->

<!--The film element lists film rolls shot.
 !-->
<xsl:template match="film">
  <xsl:call-template name="loc-child">
    <xsl:with-param name="label" select="'Film'"/>
  </xsl:call-template>
</xsl:template>

<!--================================================================-->
<!--   < p a r a >   -->

<!--The para element allows general day comments to be broken into
 !  paragraphs.
 !-->
<xsl:template match="para">
  <div class='para'>
    <xsl:apply-templates/>
  </div>
</xsl:template>

<!--================================================================-->
<!--   < g e n u s >   -->

<!--Wraps references to genus w/w/o species names that must be
 !  italicized.
 !-->
<xsl:template match="genus">
  <span class='genus'><xsl:apply-templates/></span>
</xsl:template>

<!--================================================================-->
<!--   < c i t e >   -->

<!--Wraps citations to journals, books, films, etc.
 !-->
<xsl:template match="cite">
  <span class='cite'><xsl:apply-templates/></span>
</xsl:template>

<!--================================================================-->
<!--   < f o r m >   -->

<!--form contains all the records for a given kind of bird.
 !  Most will have only an ab6 attribute giving the bird code
 !  (e.g., "saypho" for Say's Phoebe), but some will have
 !  rel="|" for one of two species or rel="^" for a hybrid,
 !  with the second bird code in the alt attribute.
 !-->
<xsl:template match="form">
  <div class="form">

    <!--'fide' records are ones I didn't see.  Place square
     !  brackets around the entire entry.
     !-->
    <xsl:if test="@fide">
      <xsl:text>[</xsl:text>
    </xsl:if>

    <!--Format the form code(s) for this record.
     !-->
    <xsl:call-template name="form-codes"/>
    <xsl:text>&#x00a0;&#x00a0;</xsl:text> <!--nonbreaking spaces-->

    <xsl:if test="@fide">
      <xsl:text>&#x00a0;(</xsl:text>
      <i><xsl:text>fide </xsl:text></i>
      <xsl:value-of select="@fide"/>
      <xsl:text>)]&#x00a0;&#x00a0;</xsl:text>
    </xsl:if>

    <!--If there are floc elements, process them separately;
     !  otherwise there's only a single entry.
     !-->
    <xsl:choose>
      <xsl:when test="floc">
        <xsl:call-template name="form-data"/>
        <xsl:apply-templates select="floc"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="form-data"/>
      </xsl:otherwise>
    </xsl:choose>
  </div>
</xsl:template>

<!--================================================================-->
<!--   f o r m - c o d e s   -->

<!--Process the form code(s) for a form element (which must be
 !  the context node).
 !-->
<xsl:template name="form-codes">
  <span class="ab6">
    <xsl:call-template name="ab6-lookup">
      <xsl:with-param name="code" select="@ab6"/>
    </xsl:call-template>
    <xsl:choose>
      <xsl:when test="@rel = '|'">
        <xsl:text>/</xsl:text>
        <xsl:call-template name="ab6-lookup">
          <xsl:with-param name="code" select="@alt"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:when test="@rel = '^'">
        <xsl:text> x </xsl:text>
        <xsl:call-template name="ab6-lookup">
          <xsl:with-param name="code" select="@alt"/>
        </xsl:call-template>
      </xsl:when>
    </xsl:choose>
  </span>

  <xsl:choose>
    <xsl:when test="@q = '?'">
      <xsl:text>?</xsl:text>
    </xsl:when>
    <xsl:when test="@q = '-'">
      <xsl:text>[uncountable]</xsl:text>
    </xsl:when>
  </xsl:choose>
</xsl:template>

<!--================================================================-->
<!--   a b 6 - l o o k u p   -->

<!--Function to translate a six-letter code to its English name
 !  as "common-generic[, common-specific]".  Argument "code" is
 !  the ab6 value to be looked up.
 !-->
<xsl:template name="ab6-lookup">
  <xsl:param name="code">**UNKNOWN**</xsl:param>
  <!--Temporarily, the taxonomic authority file is old-aou.xml,
   !  which comes from the old ~/www/nomo structure.  Eventually,
   !  rework this to use the ~/www/xnomo structure.
   !-->
  <xsl:variable name="comg">
    <xsl:value-of select="document('old-aou.xml')//ab6[@id=$code]/@com-gen"/>
  </xsl:variable>
  <xsl:variable name="coms">
    <xsl:value-of select="document('old-aou.xml')//ab6[@id=$code]/@com-sp"/>
  </xsl:variable>
  <xsl:if test="$coms">
    <xsl:value-of select="$coms"/>
    <xsl:text> </xsl:text>
  </xsl:if>
  <xsl:choose>
    <xsl:when test="$comg != ''">
      <xsl:value-of select="$comg"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:message
      >*** Unknown code (<xsl:value-of select="$code"/>)
      </xsl:message>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!--================================================================-->
<!--   < f l o c >   -->

<!--The process for a floc element is the same as for a form
 !  element, except that the form code(s) are not present, since
 !  they are shown for the parent form element.
 !-->
<xsl:template match="floc">
  <div class="floc">
    <xsl:call-template name="form-data"/>
  </div>
</xsl:template>

<!--================================================================-->
<!--   f o r m - d a t a   -->

<!--form-data:  Displays everything about a form or floc record
 !  except the species code(s).
 !-->
<xsl:template name="form-data">

  <!--Show the count, age, sex, and questionable ID elements.
   !-->
  <xsl:call-template name="age-sex-group"/>

  <!--Show the locality if given.
   !-->
  <xsl:call-template name="loc-group"/>

  <!--Show the desc, voc, etc.
   !-->
  <xsl:call-template name="other-note"/>
</xsl:template>

<!--================================================================-->
<!--   a g e - s e x - g r o u p   -->

<!--age-sex-group processes the count, age, sex, and q
 !  attributes.  These may be on either form or floc elements.
 !-->
<xsl:template name="age-sex-group">
  <xsl:if test="@count">
    <xsl:value-of select="@count"/>
    <xsl:text>&#x00a0;</xsl:text> <!--&nbsp;-->
  </xsl:if>
  <xsl:if test="@age">
    <xsl:choose>
      <xsl:when test="@age = 'p'">
        <!--Use Greek lowercase phi for female/immature
         !-->
        <xsl:text>&#x03c6;</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="@age"/>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:text>&#x00a0;</xsl:text> <!--&nbsp;-->
  </xsl:if>
  <xsl:if test="@sex">
    <xsl:choose>
      <xsl:when test="@sex = 'p'">
        <!--Use Greek lowercase phi for female/immature
         !-->
        <xsl:text>&#x03c6;</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="@sex"/>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:text>&#x00a0;</xsl:text> <!--&nbsp;-->
  </xsl:if>
</xsl:template>

<!--================================================================-->
<!--   l o c - g r o u p   -->

<!--loc-group processes all locality data.
 !-->
<xsl:template name="loc-group">
  <xsl:if test="@loc">
    <xsl:text>@</xsl:text>
    <xsl:value-of select="@loc"/>
    <xsl:text> </xsl:text>
  </xsl:if>
  <xsl:if test="@gps">
    <xsl:text>GPS=</xsl:text>
    <xsl:value-of select="@gps"/>
    <xsl:text> </xsl:text>
  </xsl:if>
  <xsl:apply-templates select="loc-detail"/>
</xsl:template>

<!--================================================================-->
<!--   < l o c - d e t a i l >   -->

<!--The loc-detail element contains all locality information.
 !-->
<xsl:template match="loc-detail">
  <xsl:call-template name="other-block">
    <xsl:with-param name="label" select="'Location'"/>
    <xsl:with-param name="text" select="."/>
  </xsl:call-template>
</xsl:template>

<!--================================================================-->
<!--   o t h e r - n o t e   -->

<!--Display desc, behavior, etc.
 !-->
<xsl:template name="other-note">
  <xsl:apply-templates select="note"/>
  <xsl:if test="desc">
    <xsl:call-template name="other-block">
      <xsl:with-param name="label" select="'Description'"/>
      <xsl:with-param name="text" select="desc"/>
    </xsl:call-template>
  </xsl:if>
  <xsl:if test="behavior">
    <xsl:call-template name="other-block">
      <xsl:with-param name="label" select="'Behavior'"/>
      <xsl:with-param name="text" select="behavior"/>
    </xsl:call-template>
  </xsl:if>
  <xsl:if test="voc">
    <xsl:call-template name="other-block">
      <xsl:with-param name="label" select="'Vocalization'"/>
      <xsl:with-param name="text" select="voc"/>
    </xsl:call-template>
  </xsl:if>
  <xsl:if test="breeding">
    <xsl:call-template name="other-block">
      <xsl:with-param name="label" select="'Breeding'"/>
      <xsl:with-param name="text" select="breeding"/>
    </xsl:call-template>
  </xsl:if>
  <xsl:if test="photo">
    <div class="loc-child">
      <span class="loc-label">
        <xsl:text>Photos: </xsl:text>
      </span>
      <xsl:apply-templates select="photo"/>
    </div>
  </xsl:if>
  <xsl:if test="para">
    <xsl:apply-templates select="para"/>
  </xsl:if>
</xsl:template>

<!--================================================================-->
<!--   < n o t e >   -->

<!--Format the note element.
 !-->
<xsl:template match="note">
  <div class='note'>
    <xsl:value-of select="text()"/>
  </div>
</xsl:template>

<!--================================================================-->
<!--   o t h e r - b l o c k   -->

<!--other-block: This named template is used to format blocks such
 !  as desc, voc, and behavior; the label argument contains the
 !  descriptive label such as "Description", and the context node's
 !  text children are displayed after that label.
 !-->
<xsl:template name="other-block">
  <xsl:param name="label"/>
  <xsl:param name="text"/>
  <div class="loc-child">
    <span class="loc-label">
      <xsl:value-of select="$label"/>
      <xsl:text>: </xsl:text>
    </span>
    <xsl:value-of select="$text"/>
  </div>
</xsl:template>

<!--================================================================-->
<!--   m a k e - l i n k   -->

<!--Build a link to another page.  Takes two arguments:
 !    target:  URL of the link target
 !    text: Link text
 !-->
<xsl:template name="make-link">
  <xsl:param name='target'/>
  <xsl:param name='text'/>
  <a href='{$target}'>
    <xsl:value-of select='$text'/>
  </a>
</xsl:template>

<!--================================================================-->
<!--   < p h o t o >   -->

<!--Process all photo catalog numbers and links.
 !-->
<xsl:template match="photo">
  <xsl:choose>
    <xsl:when test="@url">
      <a href="{@url}">
        <img src="{concat('/~shipman/thumb/', @cat-no, '.jpg')}"
             alt="{@cat-no}"/>
      </a>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="@cat-no"/>
    </xsl:otherwise>
  </xsl:choose>
  <xsl:text> </xsl:text>
</xsl:template>

<!--================================================================-->
<!--   < d a y - n o t e s >   mode="notables"   -->

<!--Process the day-notes element in "notables" mode to extract
 !  the list of notable species.
 !-->
<xsl:template mode="notables" match="day-notes">
  <xsl:variable name="notable-forms" select="form[@notable = '1']"/>
  <xsl:if test="count($notable-forms)">
    <!--There is at least one notable record.  Build the div element
     !  to contain them.
     !-->
    <div class="loc-child">
      <span class="notable">Notable:</span>
      <xsl:text>&#x00a0;</xsl:text> <!--&nbsp;-->
      <xsl:for-each select="$notable-forms">
        <xsl:if test="position() != 1">
          <xsl:text>, </xsl:text>
        </xsl:if>
        <xsl:call-template name="ab6-lookup">
          <xsl:with-param name="code" select="@ab6"/>
        </xsl:call-template>
      </xsl:for-each>
    </div>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

