Title Templates

Right, we now need to create some templates that will match our Novel-Forward-Title, Novel-Part-Title and Novel-Chapter-Title titles and process their child paragraphs. They are all pretty similar. We’ll start by taking a look at the template for Novel-Forward-Title.


<xsl:template match="text:p[@text:style-name = 'Novel-Forward-Title' or @text:style-name = /office:document/office:automatic-styles/style:style[@style:parent-style-name = 'Novel-Forward-Title']/@style:name]">
	<xsl:variable name="forwardID" select="generate-id(.)"/>
	<div id="{$forwardID}" class="forward">
		<p class="Novel-Forward-Title"><xsl:apply-templates /></p>
		<xsl:apply-templates select="key('forward', $forwardID)" />
	</div>
	<mbp:pagebreak />
</xsl:template>

The match statement is exactly the same as the one used in our $forwards variable (because we can’t use variables in match statements in xslt 1.0 we can’t just use the variable here). We then just use another variable to create an ID for the current element using “generate-id()”. This will be used both to create an “id” attribute that our table of contents links to and to select the paragraphs that are related to this forward, which we do in the select attribute of <apply-templates>. These matched paragraphs are then dealt with by our generic <text:p> template.

Our Novel-Part-Title template is very similar. The big difference you’ll see is that we have an extra <xsl:choose> statement that enables us to deal with case where the book is divided into parts but not chapters.


<xsl:template match="text:p[@text:style-name = 'Novel-Part-Title' or @text:style-name = /office:document/office:automatic-styles/style:style[@style:parent-style-name = 'Novel-Part-Title']/@style:name]">

	<xsl:variable name="partID" select="generate-id(.)"/>
	<div id="{$partID}" class="part">
		<p class="Novel-Part-Title"><xsl:apply-templates /></p>
		<mbp:pagebreak />
		<!-- Check wether this part is divided into chapters -->
		<xsl:choose>
			<xsl:when test="key('chapters', $partID)">
				<xsl:apply-templates select="key('chapters', $partID)" />
			</xsl:when>			
			<xsl:otherwise>
				<xsl:apply-templates select="key('part-paragraphs', $partID)"/>
			</xsl:otherwise>
		</xsl:choose>
	</div>
	<mbp:pagebreak />
</xsl:template>

For completeness here is our chapters template. This is should all look very familiar to you by now. The only difference here is that, as we don’t know exactly what the style name is going to be (as it could be Novel-Chapter-Title-First etc.) we have to use the same technique as our generic <text:p> template to get the style name.


<xsl:template match="text:p[contains(@text:style-name, 'Novel-Chapter-Title') or @text:style-name = /office:document/office:automatic-styles/style:style[contains(@style:parent-style-name,'Novel-Chapter-Title')]/@style:name]">

	<xsl:variable name="style"> 
	<xsl:choose>
		<xsl:when test="contains(@text:style-name,'Novel-Chapter-Title')">
			<xsl:value-of select="@text:style-name"/>
		</xsl:when>
		<xsl:otherwise>
			<xsl:value-of select="/office:document/office:automatic-styles/style:style[@style:name = current()/@text:style-name]/@style:parent-style-name"/>
		</xsl:otherwise>
	</xsl:choose>
	</xsl:variable>

	<xsl:variable name="chapterID" select="generate-id(.)"/>
	<div id="{$chapterID}" class="chapter">
		<p class="{$style}"><xsl:apply-templates /></p>
		<xsl:apply-templates select="key('paragraphs', $chapterID)" />
	</div>
</xsl:template>

If you take a look at your test document now, you should see that it is all nicely hierarchical.

Series Navigation<< Creating a Hierarchical HTML FileNeatening Things Up >>

Leave a Reply

Your email address will not be published. Required fields are marked *