After years of raiding the archive for solutions, I am finally un-lurking
and posting my own solution. I wanted to render a string as small caps
t'other day, but I couldn't find a full solution on the Internet. So, I
rolled my own, and here it is. I have included the XML input and the HTML
output (from Saxon 8). I hope no one minds a fairly lengthy post, as I
wanted to provide full detail.
XML File
------------------------------
<body>
<heading1>A String to Render in Small Caps</heading1>
</body>
------------------------------
XSL File
------------------------------
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
<xsl:template match="/">
<html>
<head>
<title>Small Cap Test</title>
</head>
<style type="text/css">
.smallCapUpper {
font-size: Larger
}
.smallCapLower
font-size: Smaller
}
</style>
<body>
<h1><xsl:apply-templates/></h1>
</body>
</html>
</xsl:template>
<xsl:template match="heading1">
<xsl:call-template name="smallCaps">
<xsl:with-param name="inString" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="smallCaps">
<xsl:param name="inString"/>
<xsl:variable name="firstLetter" select="substring($inString, 1, 1)"/>
<xsl:variable name="upperFirst" select="translate($firstLetter,
'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
<xsl:choose>
<xsl:when test="$firstLetter = $upperFirst">
<xsl:variable name="lowerTest" select="translate($inString,
'abcdefghijklmnopqrstuvwxyz', '++++++++++++++++++++++++++')"/>
<xsl:choose>
<xsl:when test="contains($lowerTest, '+')">
<xsl:variable name="upperToRemove"
select="substring-before($lowerTest, '+')"/>
<span class="smallCapUpper"><xsl:value-of
select="$upperToRemove"/></span>
<xsl:call-template name="smallCaps">
<xsl:with-param name="inString"
select="substring-after($inString, $upperToRemove)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise> <!-- test="contains($lowerTest, '+')" -->
<span class="smallCapUpper"><xsl:value-of
select="$lowerTest"/></span>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise> <!-- test="$firstLetter = $upperFirst" -->
<xsl:variable name="upperTest" select="translate($inString,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', '++++++++++++++++++++++++++')"/>
<xsl:choose>
<xsl:when test="contains($upperTest, '+')">
<xsl:variable name="lowerToRemove"
select="substring-before($upperTest, '+')"/>
<span class="smallCapLower"><xsl:value-of
select="translate($lowerToRemove, 'abcdefghijklmnopqrstuvwxyz',
'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/></span>
<xsl:call-template name="smallCaps">
<xsl:with-param name="inString"
select="substring-after($inString, $lowerToRemove)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise> <!-- test="contains($upperTest, '+')" -->
<span class="smallCapLower"><xsl:value-of
select="translate($upperTest, 'abcdefghijklmnopqrstuvwxyz',
'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/></span>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
------------------------------
HTML File
(I modified the actual output a bit so that it would be nicely formatted.
Otherwise, it's a very long line.)
------------------------------
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Small Cap Test</title>
</head>
<style type="text/css">
.smallCapUpper {
font-size: Larger
}
.smallCapLower
font-size: Smaller
}
</style>
<body>
<h1>
<span class="smallCapUpper">A S</span>
<span class="smallCapLower">TRING TO </span>
<span class="smallCapUpper">R</span>
<span class="smallCapLower">ENDER IN </span>
<span class="smallCapUpper">S</span>
<span class="smallCapLower">MALL </span>
<span class="smallCapUpper">C</span>
<span class="smallCapLower">APS</span>
</h1>
</body>
</html>
------------------------------
Jay Bryant
Bryant Communication Services