function question

It may be time to sign up for the xsl list again, but David if you get
a chance, does this look like a sensible way to correctly handle
different mods:name roles? In other words, a translator gets processed
differently than an author or editor. I’m most concerned with how I’m
using it in the function at the bottom.

<xsl:variable name=“primary-contributors” select="(‘author’,
‘editor’, ‘creator’)"/>
<xsl:variable name=“secondary-contributors” select="(‘translator’)"/>

<xsl:function name=“bib:contributor-role” as=“xs:string”>
<xsl:param name=“name” as=“element(mods:name)?”/>
xsl:value-of
xsl:choose
<xsl:when
test="$name/mods:role/mods:roleTerm[@type=‘text’]=$primary-
contributors">
xsl:textprimary</xsl:text>
</xsl:when>
<xsl:when
test="$name/mods:role/mods:roleTerm[@type=‘text’]=$secondary-
contributors">
xsl:textsecondary</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:value-of>
</xsl:function>

<xsl:function name=“bib:grouping-key” as=“xs:string”>
<xsl:param name=“bibref” as=“element(mods:mods)”/>
xsl:choose
<!–
Is the below the best way to condition the processing?

Also, needs to be “and $csl-bib/position[1]=‘not(cs:creator)’”, to
enable to properly handle reference types
where, for example, title may be the first content/sort key (like with
legal cases)
–>
<xsl:when
test="$bibref/mods:name[bib:contributor-role(.)=‘primary’]">
<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>

Followup:

How do I get this position() function to apply only to those mods:name
elements that correspond to the “primary” contributor-role values?

<xsl:when test="$contributor-role=‘primary’ and position() = last()"/>

The (global) role variable is:

<xsl:variable name=“primary-contributors” select="(‘author’, ‘editor’,
‘creator’, ‘reporter’)"/>

Source example would be:

Jane Doe translator Jane Doe author John Smith translator

The position of the second mods:name element with the author role should
be ‘1’ and it should be ‘true’ for last().

Bruce

Bruce,

I just got back in. My plan now is to simply shut down and head off
to bed now and then start with this in the morning with a fresh mind.
Ping me when you are around.

Cheers :slight_smile:

<M:D/

I’ve almost got this bit working. Bib formatting on this is now
correct; am just stuck on the citation formatting.

The example, BTW, was a book with an author (let’s say “John Doe”) and
a translator (“Susan Smith”). Earlier, both were treated the same, so I
incorrectly had (Doe and Smith) in the citation, and “Doe, J. and S.
Smith” in the bib list.

Now, I get (Doe and) for the citation, so the positional logic isn’t
working right there (a familiar theme; yes?).

Anyway, will I guess check that in when I’m in the office, and hope you
can help me fix it.

BTW, in looking through the code, I’m wondering if it’d make life
easier if we broke out the current citeproc.xsl content into two
separate files. Citeproc.xsl would only be focused on the core
processing, which is grouping/sorting/enhancing. All of the
formatting-only mods templates would then be broken out into another
file; maybe called format-mods.xsl. Or maybe we could also use another
file called group-sort.xsl, so that citeproc.xsl is then fairly
compact?

This raises a larger issue, which is whether this project will only
ever support MODS, or if there’s an elegant way to also allow other bib
formats (the most obvious one that would be suitable is the new TEI
stuff that’s coming with v5). I don’t really want to get distracted
with that now, but it’s worth keeping in mind.

Bruce

Thinking abstractly in terms of the kind of processing that needs to
happen:

The most complex two citation classes are author-year and
footnote/endnote based. The first is complex because it involves a
multi-level grouping and sorting operation – in both the bibliography
and the citations – and then along with that passing through
information (either through constructed nodes in a temporary tree, as I
do now, or in the form of parameters) that allows proper formatting in
the next step.

IIRC, that information is:

citation-style
citation-class
year publisher/issued
position within an author group (and I guess the count)
position within an author-year group (and I guess the count)

The first two are determined with a function, but given that they’re
used to sort, I assume it’s easier to just pass along the information
than to hit the functions again later?? I’m really sure about
performance optimization.

Both of the last two need to take into account what to do when there is
not an “author.” “author” in this context might be better thought of
as “primary-contributor” or “creator.”

Bruce

Bruce,

As you mentioned earlier I think its a really good idea to now start
over with a clean sheet of paper and begin to take this to the next
level that will allows a simple format definition file be enough to be
able to output to another format.

More in a bit… Im on a coding challenge at the moment which could
finally open the doors to getting a community wide push to develop an
open sylesheet template and extension library underway.

M. David Peterson wrote:

As you mentioned earlier I think its a really good idea to now start
over with a clean sheet of paper and begin to take this to the next
level that will allows a simple format definition file be enough to be
able to output to another format.

The issue I was mentioning as an aside (re: TEI) was not about output;
it was about input.

The crucial thing is fixing the sorting/grouping stuff, and perhaps now
is a good time to redo the core citeproc.xsl stuff that handles that, as
I have a small bit of of breathing space (I think!).

More in a bit… Im on a coding challenge at the moment which could
finally open the doors to getting a community wide push to develop an
open sylesheet template and extension library underway.

OK.

Bruce

OK, I checked in a partial fix for the citation author/translator
problem. The rest of the fix seems to need the same thing you did to
fix the other grouping problems, since if you look at lines 368-94,
you’ll see I’m using the same variable approach there.

David, if you can find the time, could you perhaps could suggest how to
fix this? I’m tired and your solution is a bit hard to wrap my brain
around at the moment.

Bruce

Well, I didn’t hear back, so I took a look again at the earlier code
that correctly handled grouping and sorting, and incorporated it into a
file with the existing functions. Result of messages are:

         author-position: <value-of select="1"/>
         author-year-position: <value-of select="1"/>

         author-position: <value-of select="2"/>
         author-year-position: <value-of select="1"/>

         author-position: <value-of select="2"/>
         author-year-position: <value-of select="1"/>

         author-position: <value-of select="3"/>
         author-year-position: <value-of select="1"/>

         author-position: <value-of select="4"/>
         author-year-position: <value-of select="1"/>

         author-position: <value-of select="4"/>
         author-year-position: <value-of select="2"/>

         author-position: <value-of select="5"/>
         author-year-position: <value-of select="1"/>

… which is close, but the author-position values are wrong. Also,
this take about 700 ms on my machine when run against the mods test
doc, which is not that fast (even if I have a slow machine, and am
running an older version of Saxon).

David, is this a better approach, just passing the parameter through?
Or did you have something else in mind?

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0"
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:bib="http://purl.org/NET/xbiblio/citeproc"
exclude-result-prefixes=“xdoc mods xs cs bib”>

<xsl:variable name=“biblist”>
<xsl:copy-of select=“mods:modsCollection”/>
</xsl:variable>

<xsl:template match="/">
<xsl:apply-templates mode=“enhanced-biblist”/>
</xsl:template>

<xsl:template name=“bib-enhanced-biblist” match=“mods:modsCollection"
mode=“enhanced-biblist”>
<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:variable name=“author-position” select=“position()”/>
<xsl:for-each-group select="current-group()“
group-by=“bib:year(.)”>
<xsl:sort select=“current-grouping-key()” />
<xsl:variable name=“author-year-position"
select=“position()”/>
<xsl:variable name=“year” select=“current-grouping-key()”/>
<xsl:variable name=“first” as=“xs:boolean” select=“position() = 1” />
<xsl:for-each select=“current-group()”>
<xsl:copy-of select=”.”/>
xsl:message
author-position:
author-year-position:
</xsl:message>
</xsl:for-each>
</xsl:for-each-group>
</xsl:for-each-group>
</xsl:template>

<xsl:variable name=“primary-contributors” select="(‘author’,
‘editor’, ‘creator’)"/>
<xsl:variable name=“secondary-contributors” select="(‘translator’)"/>

<xsl:function name=“bib:contributor-role” as=“xs:string”>
<xsl:param name=“name” as=“element(mods:name)?”/>
xsl:value-of
xsl:choose
<xsl:when
test="$name/mods:role/mods:roleTerm[@type=‘text’]=$primary-
contributors">
xsl:textprimary</xsl:text>
</xsl:when>
<xsl:when
test="$name/mods:role/mods:roleTerm[@type=‘text’]=$secondary-
contributors">
xsl:textsecondary</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:value-of>
</xsl:function>

<xsl:function name=“bib:year”>
<xsl:param name=“bibref” as=“element(mods:mods)”/>
<xsl:for-each select="$bibref">
<xsl:value-of
select=“substring((mods:originInfo/mods:dateIssued,
mods:relatedItem/mods:originInfo/mods:dateIssued,
mods:relatedItem/mods:part/mods:date)[1],1,4)”
/>
</xsl:for-each>
</xsl:function>
xdoc:docCollapses 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:function name=“bib:grouping-key” as=“xs:string”>
<xsl:param name=“bibref” as=“element(mods:mods)”/>
xsl:choose

<xsl:when
test="$bibref/mods:name[bib:contributor-role(.)=‘primary’]">
<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:textAnonymous</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:function>

<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:otherwisepart-inSerial</xsl:otherwise>
</xsl:choose>
</xsl:when>
xsl:otherwisemonograph</xsl:otherwise>
</xsl:choose>
</xsl:function>

<xsl:function name=“bib: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=“bib:refclass($bibref) = ‘part-inSerial’”>
<xsl:if
test="$bibref/mods:relatedItem/mods:genre=‘periodical’">
xsl:textarticle</xsl:text>
xsl:text-</xsl:text>
</xsl:if>
<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:textchapter</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
xsl:otherwise
<xsl:value-of select="$bibref/mods:genre"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
xsl:otherwisebook</xsl:otherwise>
</xsl:choose>
</xsl:value-of>
</xsl:function>

</xsl:stylesheet