Re: [xsl] Creating Drop Caps with XSL

Subject: Re: [xsl] Creating Drop Caps with XSL
From: David Carlisle <davidc@xxxxxxxxx>
Date: Tue, 12 Oct 2004 22:40:13 +0100
> Following tips from list archive, I have managed to get almost proper
> output 

ah but you didn't use the code you posted (or the source you posted)

Your source has
<content>
    <header>Some heading</header>
    <paragraph>

but your stylesheet has

<xsl:template match="div/paragraph[1]">

which doesn't match anything as their are no div elements.
I changed that to content/paragraph[1] but still the output
which is then


$ saxon drop.xml  drop.xsl
<?xml version="1.0" encoding="utf-8"?><content>
    <header>Some heading</header>
    <firstparagraph><dropcap> </dropcap> Some text  here. Some text
here<footnote number="1"/>. Some
text  here. </firstparagraph>
    <paragraph> Some text  here. </paragraph>
    <paragraph> Some text  here.</paragraph>
</content>

doesn't match your description. This doesn't lose the footnote elements
however it exhibits another problem, it dropcaps the first character,
which in this case is a space, not a printing character.

I suspect that your real code attempts to get hold of the rest of the
paragraph after the first letter by using substring(.,2) and that would
be your problem, as substring works on strings, and to get a string out
of "." it takes the string value of the element, which is the character
data, losing element nodes.

The answer to this is in the FAQ (I think) and certainly in the archives
of this list somewhere as I 've given it a few times:-)
but annyway you don't want to mess with the whole of content/paragraph,
just its first text node, so 

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>


<xsl:template match="content/paragraph[1]/text()[1]">
 <xsl:variable name="x" select="normalize-space(.)"/>
  <dropcap><xsl:value-of select="substring($x,1,1)"/></dropcap>
  <xsl:value-of select="substring($x,2)"/>
</xsl:template>
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>
</xsl:stylesheet>

$ saxon drop.xml  drop.xsl
<?xml version="1.0" encoding="utf-8"?><content>
    <header>Some heading</header>
    <paragraph><dropcap>S</dropcap>ome text here. Some text
here<footnote number
="1"/>. Some
text  here. </paragraph>
    <paragraph> Some text  here. </paragraph>
    <paragraph> Some text  here.</paragraph>
</content>


unrelated comments on your original



<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 


xmlns:fo="http://www.w3.org/1999/XSL/Format";>

You're not generating FO so you don't want this namespace.


<xsl:template match="div/paragraph[1]">
as above needs to be content not div to match your example

        <xsl:variable name="dropcap" select="substring(.,1,1)"/>

        <xsl:element name="firstparagraph">
more easily written <firstparagraph>

	<xsl:element name="dropcap">
more easily written <dropcap>

            <xsl:value-of select="$dropcap"/>
        </xsl:element>
        <xsl:apply-templates select="@*|node()"/>
	</xsl:element>
</xsl:template>
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>
</xsl:stylesheet>

________________________________________________________________________
This e-mail has been scanned for all viruses by Star. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________

Current Thread