another round

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

another round

Bruce D'Arcus
I've started to move the logic from the earlier stylesheets into the  
new approach.  Where possible, I've moved logic into functions, though  
there's a bug in one.  Ultimately, it'll need to be moved back into  
separate files, I think.

David, you there?  Are you going to be able to work on this?

===
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
version="2.0"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"  
xmlns:mods="http://www.loc.gov/mods/v3"
   xmlns="http://www.w3.org/1999/xhtml"  
xmlns:db="http://docbook.org/docbook-ng"
   xmlns:bib="http://xbiblio.sourceforge.net"  
xmlns:exist="http://exist.sourceforge.net/NS/exist"  
exclude-result-prefixes="db mods xs exist bib">

   <xsl:output method="xhtml" encoding="utf-8" indent="yes"/>
   <xsl:strip-space elements="*"/>
   <xsl:param name="citeclass">number</xsl:param>
   <xsl:param name="sort_order-bib">cited</xsl:param>
   <xsl:param name="biboutfile"/>
   <!--+ ==============================================================
   | grab all the citation pointers
   +-->
   <xsl:variable name="citerefs" select="//db:biblioref/@linkend"/>
   <!--+ ==============================================================
   | create a table against which to measure relative citation position
   +-->
   <xsl:variable name="cite-position">
     <bib:refs>
       <bib:all>
         <xsl:for-each select="$citerefs">
           <bib:ref position="{position()}" id="{generate-id()}"  
key="{.}"/>
         </xsl:for-each>
       </bib:all>
       <bib:unique>
         <xsl:for-each-group select="$citerefs" group-by=".">
           <bib:ref position="{position()}" id="{generate-id()}"  
key="{.}"/>
         </xsl:for-each-group>
       </bib:unique>
     </bib:refs>
   </xsl:variable>
   <!--+ ==============================================================
   | construct a list of unique references to pass to a query
   +-->
   <xsl:variable name="citekeys">
     <xsl:text>(</xsl:text>
     <xsl:for-each-group select="$citerefs" group-by=".">
       <xsl:if test="position() &gt; 1">,%20</xsl:if>
       <xsl:text>'</xsl:text>
       <xsl:value-of select="."/>
       <xsl:text>'</xsl:text>
     </xsl:for-each-group>
     <xsl:text>)</xsl:text>
   </xsl:variable>
   <!--+ ==============================================================
   | take list of references, and grab them from a database over
   | http; in this case it's an XQuery to eXist,but it should be
   | parameterized for flexibility
   +-->
   <xsl:variable name="bibrecord"  
select="doc(concat(&quot;http://localhost:8080/exist/servlet/db/biblio?
&quot;,    
&quot;_query=declare%20namespace%20mods=%22http://www.loc.gov/mods/
v3%22;&quot;,   &quot;%20for%20$citekey%20in%20&quot;,       $citekeys,  
   
&quot;%20return%20/mods:modsCollection/mods:
mods[@ID=$citekey]&quot;))"/>
   <!--+ ==============================================================
   | create raw bib collection
   +-->
   <xsl:variable name="raw-biblist">
     <modsCollection xmlns="http://www.loc.gov/mods/v3">
       <xsl:copy-of select="$bibrecord/exist:result/mods:mods"/>
     </modsCollection>
   </xsl:variable>
   <!--+ ==============================================================
   | group, sort, and enhance content for processing; this is where
   | most of the logic lies
   +-->
   <xsl:variable name="enhanced-biblist">
     <modsCollection xmlns:bib="http://xbiblio.sourceforge.net"  
xmlns="http://www.loc.gov/mods/v3">
       <xsl:choose>
         <xsl:when test="$sort_order-bib='citekey'">
           <xsl:for-each  
select="$raw-biblist/mods:modsCollection/mods:mods">
             <xsl:sort select="@ID"/>
             <xsl:copy-of select="."/>
           </xsl:for-each>
         </xsl:when>
         <xsl:when test="$sort_order-bib='cited'">
           <xsl:for-each  
select="$raw-biblist/mods:modsCollection/mods:mods">
             <xsl:variable name="id" select="@ID"/>
             <xsl:variable name="number">
               <xsl:value-of  
select="$cite-position/bib:refs/bib:unique/bib:ref[@key=$id]/
@position"/>
             </xsl:variable>
             <xsl:perform-sort>
               <xsl:sort select="$number"/>
             </xsl:perform-sort>
             <mods:mods ID="{$id}" position="{position()}">
               <xsl:copy-of select="mods:*"/>
             </mods:mods>
           </xsl:for-each>
         </xsl:when>
         <xsl:when test="$sort_order-bib='author-year'">
           <xsl:for-each select="$raw-biblist/mods:modsCollection">
             <xsl:variable name="bibref" select="mods:mods"/>
             <xsl:for-each-group select="$bibref"  
group-by="bib:grouping-key(.)">
               <xsl:sort select="current-grouping-key()"/>
               <xsl:for-each-group select="current-group()"  
group-by="substring((mods:originInfo/mods:dateIssued,      
mods:relatedItem/mods:originInfo/mods:dateIssued,      
mods:relatedItem/mods:part/mods:date)[1],1,4)">
                 <xsl:sort select="current-grouping-key()"/>
                 <xsl:variable name="year"  
select="current-grouping-key()"/>
                 <xsl:variable name="first" as="xs:boolean"  
select="position() = 1"/>
                 <xsl:variable name="noname-substitute">
                   <xsl:choose>
                     <xsl:when test="not(mods:name) and  
bib:refclass(.)='part-inSerial'">
                       <xsl:value-of  
select="mods:relatedItem[@type='host']/mods:titleInfo[not(@type)]/mods:
title"/>
                     </xsl:when>
                     <xsl:when test="not(mods:name) and  
not(bib:refclass(.)='part-inSerial')">
                       <xsl:text>Anonymous</xsl:text>
                     </xsl:when>
                   </xsl:choose>
                 </xsl:variable>
                 <xsl:for-each select="current-group()">
                   <mods:mods ID="{@ID}">
                     <!-- create enhanced virtual elements to help  
subsequent processing. -->
                     <bib:refclass>
                       <xsl:value-of select="bib:refclass(.)"/>
                     </bib:refclass>
                     <bib:reftype>
                       <xsl:value-of select="bib:reftype(.)"/>
                     </bib:reftype>
                     <!-- position element to handle numbering in  
certain cases; a bug because
                     all positions are now 1 -->
                     <bib:position>
                       <xsl:value-of select="position()"/>
                     </bib:position>
                     <bib:year>
                       <xsl:value-of select="current-grouping-key()"/>
                     </bib:year>
                     <!-- noname-substitute element determines what to  
do when there is no author name. -->
                     <bib:noname-substitute>
                       <xsl:value-of select="$noname-substitute"/>
                     </bib:noname-substitute>
                     <xsl:if test="last() &gt; 1">
                       <bib:key type="year-suffix">
                         <xsl:number value="position()" format="a"/>
                       </bib:key>
                     </xsl:if>
                     <xsl:copy-of select="mods:*"/>
                   </mods:mods>
                 </xsl:for-each>
               </xsl:for-each-group>
             </xsl:for-each-group>
           </xsl:for-each>
         </xsl:when>
       </xsl:choose>
     </modsCollection>
   </xsl:variable>
   <!--+ ==============================================================
   | format enhanced biblist
   +-->
   <xsl:variable name="formatted-biblist">
     <xsl:for-each  
select="$enhanced-biblist/mods:modsCollection/mods:mods">
       <xsl:variable name="id" select="@ID"/>
       <xsl:variable name="number">
         <xsl:value-of  
select="$cite-position/bib:refs/bib:unique/bib:ref[@key=$id]/
@position"/>
       </xsl:variable>
       <xsl:choose>
         <xsl:when test="$citeclass='note'">
           <p id="{@ID}">
             <xsl:value-of select="$number"/>
             <xsl:text>. </xsl:text>
             <xsl:apply-templates select="mods:titleInfo"/>
             <xsl:apply-templates select="mods:name"/>
           </p>
         </xsl:when>
         <xsl:when test="$citeclass='author-year'">
           <p id="{@ID}">
             <xsl:apply-templates select="mods:titleInfo"/>
             <xsl:apply-templates select="mods:name"/>
           </p>
         </xsl:when>
         <xsl:when test="$citeclass='number'">
           <p id="{@ID}">
             <xsl:value-of select="$number"/>
             <xsl:text>. </xsl:text>
             <xsl:apply-templates select="mods:titleInfo"/>
             <xsl:apply-templates select="mods:name"/>
           </p>
         </xsl:when>
         <xsl:when test="$citeclass='citekey'">
           <p id="{@ID}">
             <xsl:text>[</xsl:text>
             <xsl:value-of select="@ID"/>
             <xsl:text>] </xsl:text>
             <xsl:apply-templates select="mods:titleInfo"/>
             <xsl:apply-templates select="mods:name"/>
           </p>
         </xsl:when>
       </xsl:choose>
     </xsl:for-each>
   </xsl:variable>
   <!--+ ==============================================================
   | document templates
   +-->
   <xsl:template match="/">
     <html>
       <head>
         <title>Testing</title>
       </head>
       <body>
         <div id="content">
           <div id="main-content">
             <xsl:apply-templates/>
           </div>
           <div id="bibliography">
             <xsl:copy-of select="$formatted-biblist"/>
           </div>
         </div>
       </body>
     </html>
     <!--+ ==============================================================
   | write out raw MODS file if parameter is specified
   +-->
     <xsl:if test="$biboutfile">
       <xsl:result-document href="{$biboutfile}">
         <xsl:copy-of select="$raw-biblist"/>
       </xsl:result-document>
     </xsl:if>
<!-- for testing -->
     <xsl:result-document href="enhanced-mods.xml">
       <xsl:copy-of select="$enhanced-biblist"/>
     </xsl:result-document>
   </xsl:template>
   <!--+ ==============================================================
   | begin MODS templates
   +-->
   <xsl:template match="mods:titleInfo">
     <span class="title">
       <xsl:apply-templates select="mods:title"/>
       <xsl:apply-templates select="mods:subTitle"/>
     </span>
   </xsl:template>
   <xsl:template match="mods:title">
     <xsl:value-of select="."/>
   </xsl:template>
   <xsl:template match="mods:subTitle">
     <xsl:text>: </xsl:text>
     <xsl:value-of select="."/>
   </xsl:template>
   <xsl:template match="mods:name">
     <xsl:text>, </xsl:text>
     <span class="creator">
       <xsl:apply-templates select="mods:namePart[@type='family']"/>
     </span>
   </xsl:template>
   <xsl:template match="mods:namePart">
     <xsl:value-of select="."/>
   </xsl:template>
   <!--+ ==============================================================
   | begin DocBook templates
   +-->
   <xsl:template match="db:article">
     <xsl:apply-templates select="db:info"/>
     <xsl:apply-templates select="db:section"/>
   </xsl:template>
   <xsl:template match="db:section">
     <xsl:apply-templates/>
   </xsl:template>
   <xsl:template match="db:article/db:info"/>
   <xsl:template match="db:info/db:title">
     <h2>
       <xsl:apply-templates/>
     </h2>
   </xsl:template>
   <xsl:template match="db:para">
     <p>
       <xsl:apply-templates/>
     </p>
   </xsl:template>
   <!--+ ==============================================================
   | citation template
   +-->
   <xsl:template match="db:citation">
     <xsl:text>[</xsl:text>
     <xsl:for-each select="db:biblioref">
       <xsl:apply-templates select="."/>
       <xsl:if test="not(position() = last())">
         <xsl:text>, </xsl:text>
       </xsl:if>
     </xsl:for-each>
     <xsl:text>]</xsl:text>
   </xsl:template>
   <xsl:template match="db:biblioref">
     <xsl:variable name="linkend" select="@linkend"/>
     <xsl:variable name="number">
       <xsl:choose>
         <xsl:when test="$sort_order-bib='cited'">
           <xsl:value-of  
select="$cite-position/bib:refs/bib:unique/bib:ref[@key=$linkend]/
@position"/>
         </xsl:when>
         <xsl:when test="$sort_order-bib='citekey'">
           <xsl:value-of select="$linkend"/>
         </xsl:when>
         <xsl:otherwise>
           <xsl:value-of  
select="$enhanced-biblist/mods:modsCollection/mods:mods[@ID=$linkend]/
@position"/>
         </xsl:otherwise>
       </xsl:choose>
     </xsl:variable>
     <a href="#{$linkend}">
       <xsl:value-of select="$number"/>
     </a>
   </xsl:template>
   <!--+ ==============================================================
   | functions
   +-->
   <xsl:function name="bib:number-condense">
     <xsl:param name="begin"/>
     <xsl:param name="end"/>
     <xsl:choose>
       <xsl:when test="$begin castable as xs:integer">
         <xsl:variable name="begin" select="$begin" as="xs:integer"/>
         <xsl:choose>
           <xsl:when test="$begin gt 100 and $begin mod 100 and $begin  
idiv 100 eq $end idiv 100">
             <xsl:value-of select="$end mod 100"/>
           </xsl:when>
           <xsl:otherwise>
             <xsl:value-of select="$end"/>
           </xsl:otherwise>
         </xsl:choose>
       </xsl:when>
       <xsl:otherwise>
         <xsl:value-of select="$end"/>
       </xsl:otherwise>
     </xsl:choose>
   </xsl:function>
   <!--+ ==============================================================
   | bib:grouping-key constructs an authors string for grouping and
   | sorting. Where no author exists, it substituttes periodical title
   | if applicable, or uses "Anonymous."
   +-->
   <xsl:function name="bib:grouping-key" as="xs:string">
     <xsl:param name="bibref" as="element(mods:mods)"/>
     <xsl:choose>
       <xsl:when test="$bibref/mods:name">
         <xsl:value-of separator=";">
           <xsl:for-each select="$bibref/mods:name">
             <xsl:value-of select="string-join((mods:namePart[@type =  
'family']|      mods:namePart[not(@type)],              
mods:namePart[@type = 'given']), ',')"/>
           </xsl:for-each>
         </xsl:value-of>
       </xsl:when>
       <xsl:otherwise>
         <xsl:choose>
           <xsl:when  
test="$bibref/mods:relatedItem[@type='host']/mods:originInfo/mods:
issuance = 'continuing'">
             <xsl:for-each select="$bibref">
               <xsl:value-of  
select="mods:relatedItem[@type='host']/mods:titleInfo[not(@type)]/mods:
title"/>
             </xsl:for-each>
           </xsl:when>
           <xsl:otherwise>
             <xsl:text>Anonymous</xsl:text>
           </xsl:otherwise>
         </xsl:choose>
       </xsl:otherwise>
     </xsl:choose>
   </xsl:function>
   <!--+ ==============================================================
   | The bib:refclass function classifies records into classes
   | based on the structural characteristics. This is central
   | to the formatting logic of the system.
   +-->
   <xsl:function name="bib:refclass" as="xs:string">
     <xsl:param name="bibref" as="element(mods:mods)?"/>
     <xsl:choose>
       <xsl:when test="$bibref/mods:relatedItem[@type='host']">
         <xsl:variable name="issuance"  
select="$bibref/mods:relatedItem/mods:originInfo/mods:issuance"/>
         <xsl:choose>
           <xsl:when  
test="$issuance='monographic'">part-inMonograph</xsl:when>
           <xsl:otherwise>part-inSerial</xsl:otherwise>
         </xsl:choose>
       </xsl:when>
       <xsl:otherwise>monograph</xsl:otherwise>
     </xsl:choose>
   </xsl:function>
   <!--+ ==============================================================
   | The bib:reftype function further classifies records into types based
   | on the class. These types then map onto the citation style langauge
   | definitions. Article, chapter and book are the default structures
   | and generic fallbacks. Most records will be formatted with these  
"types."
   |
   | Beyond these core types, additional types would be defined by
   | both their genre values and their likeness to the core
   | types. The value be multi-level where applicable: e.g.  
"article-magazine".
   | Howver, I'm getting an error on the code below.
   +-->
   <xsl:function name="bib:reftype" as="xs:string">
     <xsl:param name="bibref" as="element(mods:mods)?"/>
     <xsl:choose>
       <xsl:when test="$bibref/mods:relatedItem/@type = 'host'">
         <xsl:variable name="issuance"  
select="$bibref/mods:relatedItem/mods:originInfo/mods:issuance"/>
         <xsl:choose>
           <xsl:when test="bib:refclass($bibref) = 'part-inSerial'">
             <xsl:text>article</xsl:text>
             <!--
             this code introduces a sequence error; don't know why
             <xsl:text>-</xsl:text>
             <xsl:value-of  
select="$bibref/mods:relatedItem/mods:genre"/> -->
           </xsl:when>
           <xsl:when test="bib:refclass($bibref) = 'part-inMonograph'">
             <xsl:choose>
               <xsl:when test="$bibref/mods:genre">
                 <xsl:value-of select="$bibref/mods:genre"/>
               </xsl:when>
               <xsl:otherwise>
                 <xsl:text>chapter</xsl:text>
               </xsl:otherwise>
             </xsl:choose>
           </xsl:when>
           <xsl:otherwise>
             <xsl:value-of select="$bibref/mods:genre"/>
           </xsl:otherwise>
         </xsl:choose>
       </xsl:when>
       <xsl:otherwise>book</xsl:otherwise>
     </xsl:choose>
   </xsl:function>
</xsl:stylesheet>
===

Bruce