<xsl:stylesheet xmlns:bib="http://purl.org/NET/xbiblio/citeproc" xmlns:cs="http://purl.org/NET/xbiblio/csl" xmlns:db="http://docbook.org/ns/docbook" xmlns:mods="http://www.loc.gov/mods/v3" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xdoc="http://www.pnp-software.com/XSLTdoc" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" exclude-result-prefixes="xdoc mods xs cs bib">
<!-- === licensed under CC-GNU GPL; see http://creativecommons.org/licenses/GPL/2.0 === -->
<!-- |||| date functions |||| -->
<xsl:function name="mods:year">
<xsl:param name="bibref" as="element(mods:mods)" />
<xsl:for-each select="$bibref">
<xsl:variable name="xsd-date" select="(mods:originInfo/mods:dateIssued, mods:relatedItem/mods:originInfo/mods:dateIssued, mods:relatedItem/mods:part/mods:date)[1]" />
<xsl:value-of select="substring($xsd-date,1,4)" />
</xsl:for-each>
</xsl:function>
<!-- |||| number handling 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="xs:integer($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>
<xsl:variable name="primary-contributors" select="('author', 'editor', 'creator', 'speaker', 'reviewer')" />
<xsl:variable name="secondary-contributors" select="('translator')" />
<xsl:function name="mods:grouping-key" as="xs:string">
<xsl:param name="bibref" as="element(mods:mods)" />
<xsl:variable name="sort-on" select="mods:sort_on($bibref)" as="xs:string" />
<xsl:choose>
<xsl:when test="$sort-on='creator'">
<xsl:value-of separator=";">
<xsl:for-each select="$bibref/mods:name[mods:role/mods:roleTerm=$primary-contributors]">
<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:when test="$sort-on='container-title'">
<xsl:value-of select="$bibref/mods:relatedItem[@type='host']/mods:titleInfo/mods:title" />
</xsl:when>
<xsl:when test="$sort-on='title'">
<xsl:value-of select="$bibref/mods:titleInfo/mods:title" />
</xsl:when>
<xsl:when test="$sort-on='anonymous'">
<xsl:value-of select="'Anonymous'" />
</xsl:when>
</xsl:choose>
</xsl:function>
<xsl:function name="mods:sort_on" as="xs:string">
<xsl:param name="bibref" as="element(mods:mods)" />
<xsl:variable name="use-reftype" select="mods:use_csl-reftype($bibref)" />
<xsl:variable name="csl_path" select="if ($citeclass='note-nobib') then $style-citation/cs:first/cs:layout/cs:reftype[@name=$use-reftype] else $style-biblio/cs:layout/cs:reftype[@name=$use-reftype]" />
<xsl:choose>
<xsl:when test="$csl_path/cs:creator[1]">
<xsl:choose>
<xsl:when test="$bibref/mods:name[mods:role/mods:roleTerm=$primary-contributors]">
<xsl:value-of select="'creator'" />
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$csl_path/cs:creator/@alternate-sortkey='container-title'">
<xsl:value-of select="'container-title'" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'anonymous'" />
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$csl_path/cs:title[1]">
<xsl:value-of select="'title'" />
</xsl:when>
</xsl:choose>
</xsl:function>
<xsl:function name="mods:use_csl-reftype" as="xs:string">
<xsl:param name="bibref" as="element(mods:mods)" />
<xsl:sequence select="if (mods:csl-reftype($bibref)) then (mods:csl-reftype($bibref)) else (mods:csl-fallback($bibref))" />
</xsl:function>
<xsl:function name="mods:csl-reftype" as="xs:string">
<xsl:param name="bibref" as="element(mods:mods)" />
<xsl:variable name="reftype" select="mods:reftype($bibref)" />
<xsl:variable name="csl-style" select="if ($citeclass='note-nobib') then ($style-citation/cs:first/cs:layout/cs:reftype) else ($style-biblio/cs:layout/cs:reftype)" />
<xsl:value-of select="$csl-style/@name[.=$reftype]" />
</xsl:function>
<xsl:function name="mods:csl-fallback" as="xs:string">
<xsl:param name="bibref" as="element(mods:mods)" />
<xsl:variable name="bibrefclass" select="mods:refclass($bibref)" />
<xsl:choose>
<xsl:when test="$bibrefclass='monograph'">
<xsl:value-of select="'book'" />
</xsl:when>
<xsl:when test="$bibrefclass='part-inMonograph'">
<xsl:value-of select="'chapter'" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'article'" />
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:function name="mods: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>
<xsl:function name="mods:reftype" as="xs:string">
<xsl:param name="bibref" as="element(mods:mods)?" />
<xsl:value-of>
<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="mods:refclass($bibref) = 'part-inSerial'">
<xsl:if test="$bibref/mods:relatedItem/mods:genre=('periodical', 'magazine', 'academic journal', 'newspaper')">
<xsl:text>article</xsl:text>
<xsl:text>-</xsl:text>
</xsl:if>
<xsl:value-of select="($bibref/mods:relatedItem/mods:genre, $bibref/mods:genre)[1]" />
</xsl:when>
<xsl:when test="mods: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:value-of>
</xsl:function>
<xsl:function name="bib:number-footcite" as="xs:string">
<xsl:param name="footcite" as="element()" />
<xsl:choose>
<xsl:when test="$chapters/db:chapter">
<xsl:for-each select="$footcite">
<xsl:number level="any" select="." count="db:footnote|db:citation[not(ancestor::db:footnote)]" from="db:chapter" />
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="$footcite">
<xsl:number level="any" select="." count="db:footnote|db:citation[not(ancestor::db:footnote)]" />
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:function name="bib:first-reference" as="xs:boolean">
<xsl:param name="cite-ref" as="node()" />
<xsl:sequence select="$cite-ref is key('refs', $cite-ref/@linkend, root($cite-ref))[1]" />
</xsl:function>
<xsl:function name="bib:ibid" as="xs:boolean">
<xsl:param name="citation" as="node()" />
<xsl:sequence select="$citation/db:biblioref/@linkend = $citation/preceding::db:biblioref[1]/@linkend" />
</xsl:function>
</xsl:stylesheet>
<!-- === licensed under CC-GNU GPL; see http://creativecommons.org/licenses/GPL/2.0 === -->
<xdoc:doc type="stylesheet">
<xdoc:short>CiteProc functions.</xdoc:short>
<xdoc:author>Bruce D’Arcus</xdoc:author>
<xdoc:copyright>2004</xdoc:copyright>
</xdoc:doc>
<xdoc:short>CiteProc functions.</xdoc:short>
<xdoc:author>Bruce D’Arcus</xdoc:author>
<xdoc:copyright>2004</xdoc:copyright>
</xdoc:doc>
<!-- |||| date functions |||| -->
<xsl:function name="mods:year">
<xsl:param name="bibref" as="element(mods:mods)" />
<xsl:for-each select="$bibref">
<xsl:variable name="xsd-date" select="(mods:originInfo/mods:dateIssued, mods:relatedItem/mods:originInfo/mods:dateIssued, mods:relatedItem/mods:part/mods:date)[1]" />
<xsl:value-of select="substring($xsd-date,1,4)" />
</xsl:for-each>
</xsl:function>
<!-- |||| number handling functions |||| -->
<xdoc:doc>Collapses a page range according to the Chicago algorithm. Probably needs to be
generalized.</xdoc:doc>
generalized.</xdoc:doc>
<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="xs:integer($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>
<xsl:variable name="primary-contributors" select="('author', 'editor', 'creator', 'speaker', 'reviewer')" />
<xsl:variable name="secondary-contributors" select="('translator')" />
<xdoc:doc>Constructs an authors string for grouping and sorting. This function concatenates all
authors into a string so that multiple-authors get correctly grouped. Where no author exists it
substitutes based on CSL definitions.</xdoc:doc>
authors into a string so that multiple-authors get correctly grouped. Where no author exists it
substitutes based on CSL definitions.</xdoc:doc>
<xsl:function name="mods:grouping-key" as="xs:string">
<xsl:param name="bibref" as="element(mods:mods)" />
<xsl:variable name="sort-on" select="mods:sort_on($bibref)" as="xs:string" />
<xsl:choose>
<xsl:when test="$sort-on='creator'">
<xsl:value-of separator=";">
<xsl:for-each select="$bibref/mods:name[mods:role/mods:roleTerm=$primary-contributors]">
<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:when test="$sort-on='container-title'">
<xsl:value-of select="$bibref/mods:relatedItem[@type='host']/mods:titleInfo/mods:title" />
</xsl:when>
<xsl:when test="$sort-on='title'">
<xsl:value-of select="$bibref/mods:titleInfo/mods:title" />
</xsl:when>
<xsl:when test="$sort-on='anonymous'">
<xsl:value-of select="'Anonymous'" />
</xsl:when>
</xsl:choose>
</xsl:function>
<xsl:function name="mods:sort_on" as="xs:string">
<xsl:param name="bibref" as="element(mods:mods)" />
<xsl:variable name="use-reftype" select="mods:use_csl-reftype($bibref)" />
<xsl:variable name="csl_path" select="if ($citeclass='note-nobib') then $style-citation/cs:first/cs:layout/cs:reftype[@name=$use-reftype] else $style-biblio/cs:layout/cs:reftype[@name=$use-reftype]" />
<xsl:choose>
<xsl:when test="$csl_path/cs:creator[1]">
<xsl:choose>
<xsl:when test="$bibref/mods:name[mods:role/mods:roleTerm=$primary-contributors]">
<xsl:value-of select="'creator'" />
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$csl_path/cs:creator/@alternate-sortkey='container-title'">
<xsl:value-of select="'container-title'" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'anonymous'" />
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$csl_path/cs:title[1]">
<xsl:value-of select="'title'" />
</xsl:when>
</xsl:choose>
</xsl:function>
<xsl:function name="mods:use_csl-reftype" as="xs:string">
<xsl:param name="bibref" as="element(mods:mods)" />
<xsl:sequence select="if (mods:csl-reftype($bibref)) then (mods:csl-reftype($bibref)) else (mods:csl-fallback($bibref))" />
</xsl:function>
<xsl:function name="mods:csl-reftype" as="xs:string">
<xsl:param name="bibref" as="element(mods:mods)" />
<xsl:variable name="reftype" select="mods:reftype($bibref)" />
<xsl:variable name="csl-style" select="if ($citeclass='note-nobib') then ($style-citation/cs:first/cs:layout/cs:reftype) else ($style-biblio/cs:layout/cs:reftype)" />
<xsl:value-of select="$csl-style/@name[.=$reftype]" />
</xsl:function>
<xsl:function name="mods:csl-fallback" as="xs:string">
<xsl:param name="bibref" as="element(mods:mods)" />
<xsl:variable name="bibrefclass" select="mods:refclass($bibref)" />
<xsl:choose>
<xsl:when test="$bibrefclass='monograph'">
<xsl:value-of select="'book'" />
</xsl:when>
<xsl:when test="$bibrefclass='part-inMonograph'">
<xsl:value-of select="'chapter'" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'article'" />
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xdoc:doc>This function is central to the formatting logic of the system. The fallback system
classifies records into one of three structural classes: part-inMongraph, part-inSerial, and
mongraph. It would be easy to add serial as a fourth, but I have not yet found the need (does
one ever cite a serial as a whole?).</xdoc:doc>
classifies records into one of three structural classes: part-inMongraph, part-inSerial, and
mongraph. It would be easy to add serial as a fourth, but I have not yet found the need (does
one ever cite a serial as a whole?).</xdoc:doc>
<xsl:function name="mods: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>
<xdoc:doc>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 can be multi-level where applicable: e.g. “article-magazine.”</xdoc:doc>
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 can be multi-level where applicable: e.g. “article-magazine.”</xdoc:doc>
<xsl:function name="mods:reftype" as="xs:string">
<xsl:param name="bibref" as="element(mods:mods)?" />
<xsl:value-of>
<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="mods:refclass($bibref) = 'part-inSerial'">
<xsl:if test="$bibref/mods:relatedItem/mods:genre=('periodical', 'magazine', 'academic journal', 'newspaper')">
<xsl:text>article</xsl:text>
<xsl:text>-</xsl:text>
</xsl:if>
<xsl:value-of select="($bibref/mods:relatedItem/mods:genre, $bibref/mods:genre)[1]" />
</xsl:when>
<xsl:when test="mods: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:value-of>
</xsl:function>
<xsl:function name="bib:number-footcite" as="xs:string">
<xsl:param name="footcite" as="element()" />
<xsl:choose>
<xsl:when test="$chapters/db:chapter">
<xsl:for-each select="$footcite">
<xsl:number level="any" select="." count="db:footnote|db:citation[not(ancestor::db:footnote)]" from="db:chapter" />
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="$footcite">
<xsl:number level="any" select="." count="db:footnote|db:citation[not(ancestor::db:footnote)]" />
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xdoc:doc>Determines the first time a reference is cited in the text. Necesary for those styles
that make a formatting distinction between first and subsequent references.</xdoc:doc>
that make a formatting distinction between first and subsequent references.</xdoc:doc>
<xsl:function name="bib:first-reference" as="xs:boolean">
<xsl:param name="cite-ref" as="node()" />
<xsl:sequence select="$cite-ref is key('refs', $cite-ref/@linkend, root($cite-ref))[1]" />
</xsl:function>
<xsl:function name="bib:ibid" as="xs:boolean">
<xsl:param name="citation" as="node()" />
<xsl:sequence select="$citation/db:biblioref/@linkend = $citation/preceding::db:biblioref[1]/@linkend" />
</xsl:function>
</xsl:stylesheet>
v