Back
Word

Bibliography & Citations 102 – Building Custom styles

My name is Nathan Kwan. I am a PM intern on the Microsoft Word team. My internship started in early January and is sadly coming to an end at the end of April. I’m a 4th year student at the University of Waterloo working towards my Software Engineering degree.

When I started on the team, I was given the bibliography feature. Being a student myself, I am a fan, so I was pretty excited to dig into it.

What will this post cover?

In Amani’s last post, she showed you how to setup and build a simple bibliography style. We learned that bibliography styles in Word are XSLTs. We also found that we could drop our own custom styles in C:Program FilesMicrosoft OfficeOffice12BibliographyStyle and Word will display them.

Today, I’m going to be expanding on Amani’s post to show you how to build more complex styles. One of the issues that “complicates” bibliography styles is that they often need to have a significant amount of conditional logic built into them. For example, if the date is specified we need to show the date, whereas if the date is not specified we may need to use an abbreviation to indicate that there is no date for that source.

For a more specific example, in the APA style, if a date is not specified for a website source, then the abbreviation n.d. is used to denote no date…and the style should do this automatically. The example is shown below:

APA website source with no date entered:

Kwan, N. (n.d.). Retrieved from www.microsoft.com

APA website source with date entered:

Kwan, N. (2006, Jan 18). Retrieved from www.microsoft.com

As you can see, what is displayed is conditional on the data entered.

Unfortunately, there is not enough space or time in this blog to go through each and every rule that a new style would need, but I will provide a foundation for you to create new styles by showing you step by step how to implement a single rule that leverages conditional logic.

The rule I will be showing is one of the most common rules. The output of virtually every style needs to change depending on whether you have a “Corporate Author” or a “Normal Author”.

I’m going to show you how to display a corporate author if the corporate author is specified and display a normal author if the corporate author is not specified.

Overview of Solution

To display a corporate author only if it is filled in, we need to take the following actions:

  1. Add a variable to count the number of corporate authors in the citation section of the code
  2. Display the corporate author in the citation if the corporate author is filled in. Display the normal author in the citation if the corporate author is not filled in.
  3. Add a variable to count the number of corporate authors in the bibliography section of the code
  4. Display the corporate author in the bibliography if the corporate author is filled in. Display the normal author in the bibliography if the corporate author is not filled in.

Getting Started

Let’s start by changing the citation. This is the code for citations from last time:

<!– Defines the output of the Citation –>

<xsl:template match=”b:Citation/b:Source[b:SourceType = 'Book']“>

<html xmlns=”http://www.w3.org/TR/REC-html40″>

<body>

<!– Defines the output format as (Author, Year)–>

<xsl:text>(</xsl:text>

<xsl:value-of select=”b:Author/b:Author/b:NameList/b:Person/b:Last”/>

<xsl:text>, </xsl:text>

<xsl:value-of select=”b:Year”/>

<xsl:text>)</xsl:text>

</body>

</html>

</xsl:template>

……

    

Step 1: Define a new variable in the citation section to count the number of Corporate Authors

We’ll need to be declaring a new variable to help us determine whether a corporate author is available. This variable is a count on the number of times the corporate author field exists in our source.

<!– Defines the output of the Citation –>

<html xmlns=”http://www.w3.org/TR/REC-html40″>

<!–Count the number of Corporate Authors (can only be 0 or 1)–>

<xsl:variable name=”cCorporateAuthors”>

<xsl:value-of select=”count(b:Author/b:Author/b:Corporate)” />

</xsl:variable>

……

Step 2: Check to see whether the corporate author has been filled in

Now that we have this new variable, we need to check if the corporate author has been filled in. We can do this by checking if the count on corporate authors is not zero. If a corporate author exists, display it. If it does not exist, display the normal author.

……

<xsl:text>(</xsl:text>

<xsl:choose>

<!–when the corporate author exists display the corporate author–>

<xsl:when test =”$cCorporateAuthors!=0″>

<xsl:value-of select=”b:Author/b:Author/b:Corporate”/>

</xsl:when>

<!– when the corporate author does not exist, display the normal author–>

<xsl:otherwise>

<xsl:value-of select=”b:Author/b:Author/b:NameList/b:Person/b:Last”/>

</xsl:otherwise>

</xsl:choose>

<xsl:text>, </xsl:text>

…….

Now that we made the change for citations, let’s make the change for our bibliography. Here’s the bibliography section from the original post:

……

<!– Defines the output format for a simple Book (in the Bibliography) with important fields defined –>

<xsl: template match=”b:Source[b:SourceType = 'Book']“>

<!–Label the paragraph as an Office Bibliography paragraph –>

<p>

<xsl:value-of select=”b:Author/b:Author/b:NameList/b:Person/b:Last”/>

<xsl:text>, </xsl:text>

<xsl:value-of select=”b:Author/b:Author/b:NameList/b:Person/b:First”/>

<xsl:text>. (</xsl:text>

<xsl:value-of select=”b:Year”/>

<xsl:text>). </xsl:text>

<i>

……

Step 3: Define a new variable in the bibliography section

Once again, let’s start by adding a counting variable.

……

<!– Defines the output format for a simple Book (in the Bibliography) with important fields defined –>

<xsl: template match=”b:Source[b:SourceType = 'Book']“>

<! –Count the number of Corporate Authors (can only be 0 or 1)–>

<xsl:variable name=”cCorporateAuthors”>

<xsl:value-of select=”count(b:Author/b:Author/b:Corporate)” />

</xsl:variable>

……

Step 4: Check to see whether the corporate author has been filled in

Now let’s add the check to see if a corporate author exists.

……

<xsl:variable name=”cCorporateAuthors”>

<xsl:value-of select=”count(b:Author/b:Author/b:Corporate)” />

</xsl:variable>

<p>

<xsl:choose>

<!–when the corporate author exists display the corporate author–>

<xsl:when test =”$cCorporateAuthors!=0″>

<xsl:value-of select=”b:Author/b:Author/b:Corporate”/>

<xsl:text>. (</xsl:text>

</xsl:when>

<xsl:otherwise>

<!– when the corporate author does not exist, display the normal author –>

<xsl:value-of select=”b:Author/b:Author/b:NameList/b:Person/b:Last”/>

<xsl:text>, </xsl:text>

<xsl:value-of select=”b:Author/b:Author/b:NameList/b:Person/b:First”/>

<xsl:text>. (</xsl:text>

</xsl:otherwise>

</xsl:choose>

……

End Result

Now when we use a corporate author, it displays correctly in both our citation and bibliography!

This technique can be extended to perform any conditional statement we may need in our style.

Here’s the final code that was used:

<?xml version=”1.0″ ?>

<!– List of the external resources that we are referencing –>

<xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” xmlns:msxsl=”urn:schemas-microsoft-com:xslt” xmlns:b=”http://schemas.openxmlformats.org/officeDocument/2006/bibliography”>

<!– When the bibliography or citation is in your document, it’s just HTML –>

<xsl:output method=”html” encoding=”us-ascii”/>

<!– match the root element, and dispatch to its children –>

<xsl:template match=”/”>

<xsl:apply-templates select=”*” />

</xsl:template>

<!–set an optional version number for this style–>

<xsl:template match=”b:version”>

<xsl:text>2006.5.07</xsl:text>

</xsl:template>

<!– Defines the name of the style in the References dropdown –>

<xsl:template match=”b:StyleName”>

<xsl:text>Simple Book Style</xsl:text>

</xsl:template>

<!– Specifies which fields should appear in the Create Source dialog when in a collapsed state (The Show All Bibliography Fieldscheckbox is cleared) –>

<xsl:template match=”b:GetImportantFields[b:SourceType = 'Book']“>

<b:ImportantFields>

<b:ImportantField>

<xsl:text>b:Author/b:Author/b:NameList</xsl:text>

</b:ImportantField>

<b:ImportantField>

<xsl:text>b:Title</xsl:text>

</b:ImportantField>

<b:ImportantField>

<xsl:text>b:Year</xsl:text>

</b:ImportantField>

<b:ImportantField>

<xsl:text>b:City</xsl:text>

</b:ImportantField>

<b:ImportantField>

<xsl:text>b:Publisher</xsl:text>

</b:ImportantField>

</b:ImportantFields>

</xsl:template>

<!– Defines the output format for a simple Book (in the Bibliography) with important fields defined –>

<xsl:template match=”b:Source[b:SourceType = 'Book']“>

<!–Count the number of Corporate Authors (can only be 0 or 1)–>

<xsl:variable name=”cCorporateAuthors”>

<xsl:value-of select=”count(b:Author/b:Author/b:Corporate)” />

</xsl:variable>

<!--Label the paragraph as an Office Bibliography paragraph –>

<p>

<xsl:choose>

<xsl:when test =”$cCorporateAuthors!=0″>

<!– when the corporate author exists display the corporate author–>

<xsl:value-of select=”b:Author/b:Author/b:Corporate”/>

<xsl:text>. (</xsl:text>

</xsl:when>

<xsl:otherwise>

<!– when the corporate author does not exist, display the normal author–>

<xsl:value-of select=”b:Author/b:Author/b:NameList/b:Person/b:Last”/>

<xsl:text>, </xsl:text>

<xsl:value-of select=”b:Author/b:Author/b:NameList/b:Person/b:First”/>

<xsl:text>. (</xsl:text>

</xsl:otherwise>

</xsl:choose>

<xsl:value-of select=”b:Year”/>

<xsl:text>). </xsl:text>

<i>

<xsl:value-of select=”b:Title”/>

<xsl:text>. </xsl:text>

</i>

<xsl:value-of select=”b:City”/>

<xsl:text>: </xsl:text>

<xsl:value-of select=”b:Publisher”/>

<xsl:text>.</xsl:text>

</p>

</xsl:template>

<!– Defines the output of the entire Bibliography –>

<xsl:template match=”b:Bibliography”>

<html xmlns=”http://www.w3.org/TR/REC-html40″>

<body>

<xsl:apply-templates select =”*”>

</xsl:apply-templates>

</body>

</html>

</xsl:template>

<!– Defines the output of the Citation –>

<xsl:template match=”b:Citation/b:Source[b:SourceType = 'Book']“>

<html xmlns=”http://www.w3.org/TR/REC-html40″>

<xsl:variable name=”cCorporateAuthors”>

<xsl:value-of select=”count(b:Author/b:Author/b:Corporate)” />

</xsl:variable>

<body>    

<!– Defines the output format as (Author, Year)–>

<xsl:text>(</xsl:text>

<xsl:choose>

<!– when the corporate author exists display the corporate author–>

<xsl:when test =”$cCorporateAuthors!=0″>

<xsl:value-of select=”b:Author/b:Author/b:Corporate”/>

</xsl:when>

<!– when the corporate author does not exist, display the normal author–>

<xsl:otherwise>

<xsl:value-of select=”b:Author/b:Author/b:NameList/b:Person/b:Last”/>

</xsl:otherwise>

</xsl:choose>

<xsl:text>, </xsl:text>

<xsl:value-of select=”b:Year”/>

<xsl:text>)</xsl:text>

</body>

</html>

</xsl:template>

<xsl:template match=”text()” />

</xsl:stylesheet>

In conclusion, we built off of Amani’s post to build a more complex style using conditional statements. The unfortunately reality is that bibliography styles are complex, but as this example shows, implementing the individual rule does not have to be.

-Nathan