<
xsl:
stylesheet xmlns:xsl="
http://www.w3.org/1999/XSL/Transform"
xmlns:xdoc="
http://www.pnp-software.com/XSLTdoc"
xmlns:xs="
http://www.w3.org/2001/XMLSchema"
xmlns:mods="
http://www.loc.gov/mods/v3"
xmlns:cs="
http://purl.org/NET/xbiblio/csl"
xmlns:db="
http://docbook.org/ns/docbook"
xmlns:bib="
http://purl.org/NET/xbiblio/citeproc"
version="
2.0"
exclude-result-prefixes="
xdoc mods xs cs bib">
<!---->
<
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:
doc>
when given a bibliographic record, returns its publication year</
xdoc:
doc>
<
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>
<!---->
<
xdoc:
doc>
Collapses a page range according to the Chicago algorithm. Probably needs to be
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>
<
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>
<
xdoc:
doc>
Determines what to sort on.</
xdoc:
doc>
<
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>
<
xdoc:
doc>
Determines which CSL definition to use for any given MODS record.</
xdoc:
doc>
<
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>
<
xdoc:
doc>
Maps a MODS reference type to a CSL XPATH expression.</
xdoc:
doc>
<
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>
<
xdoc:
doc>
Determines the CSL fallback for a MODS record.</
xdoc:
doc>
<
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>
<
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>
<
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>
<
xdoc:
doc>
Numbers citations and foot/endnotes together.</
xdoc:
doc>
<
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>
<
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>
<
xdoc:
doc>
Determines when a citation fulfills the "ibid" condition.</
xdoc:
doc>
<
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