Newer
Older
XML / format-master.xml
<?xml version="1.0"?>
<!-- This will mostly be a list of element names to match, along with the corresponding HTML and LaTeX handling XSLT code. -->
<stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

	<template name="PaperCode" match="PaperCode">
		<common>
			<xsl:value-of select="$department"/>
			<xsl:text> </xsl:text>
			<xsl:value-of select="$paper"/>
		</common>
	</template>

	<template name="OracleServer" match="OracleServer">
		<latex>Oracle9\textit{i}</latex>
		<html>Oracle9<I>i</I></html>
	</template>

	<template name="Blackboard" match="Blackboard">
		<common>
			<xsl:call-template name="hyperlink-internal">
				<xsl:with-param name="url">http://blackboard.otago.ac.nz/</xsl:with-param>
				<xsl:with-param name="label">Blackboard</xsl:with-param>
			</xsl:call-template>
		</common>
	</template>

	<!--
		Plain paragraph.
		
		@indent: Whether or not to indent this paragraph (probably only
		relevant in LaTeX).
			'no' => don't indent.
			otherwise => apply standard paragraph formatting. [default]
		
		@align: How to align the paragraph. Note that these are
		potentially distinct from the default action, e.g., specifying
		align="left" will produce a flushleft environment in LaTeX,
		which is not the same effect as not specifying an alignment.
			'left' => left alignment
			'center' => centered alignment
			'right' => right alignment
	-->
	<template name="paragraph" match="paragraph|para|p|P">
		<latex>
			<xsl:text>


			</xsl:text>
			<xsl:choose>
				<xsl:when test="(@align = 'left') or (@align = 'right')">
					<xsl:text>\begin{flush</xsl:text>
					<xsl:value-of select="@align"/>
					<xsl:text>}</xsl:text>
					<xsl:apply-templates/>
					<xsl:text>\end{flush</xsl:text>
					<xsl:value-of select="@align"/>
					<xsl:text>}</xsl:text>
				</xsl:when>
				<xsl:when test="@align = 'center'">
					<xsl:text>\begin{center}</xsl:text>
					<xsl:apply-templates/>
					<xsl:text>\end{center}</xsl:text>
				</xsl:when>
				<xsl:otherwise>
					<xsl:if test="@indent = 'no'">\noindent </xsl:if>
					<xsl:apply-templates/>
				</xsl:otherwise>
			</xsl:choose>
			<xsl:text>
	
		
			</xsl:text>
		</latex>
		<!-- HTML is weird about what things you cannot include inside paragraphs (e.g. lists of any kind).  However, the end P tag is optional, so one option might simply be not to output it. -->
		<html>
			<!--
				The HTMLStyle parameter is an Ugly Hack(tm) to ensure
				that paragraphs are indented correctly inside definition
				lists in HTML. I tried modes first, but they didn't work
				correctly. Fortunately this only needs to be done with
				paragraphs, so this will work fine.
			-->
			<xsl:param name="HTMLStyle"/>
			<P>
				<xsl:if test="$HTMLStyle">
					<xsl:attribute name="CLASS">
						<xsl:value-of select="$HTMLStyle"/>
					</xsl:attribute>
				</xsl:if>
				<xsl:if test="@align">
					<xsl:attribute name="ALIGN">
						<xsl:value-of select="@align"/>
					</xsl:attribute>
				</xsl:if>
				<xsl:apply-templates/>
			</P>
		</html>
	</template>
	
	<!-- Special characters (should maybe all be named, in case they need to be called explicitly with xsl:call-template) -->
	<!-- I'd like to use the Unicode names for these; will look them up some time! -->
	<template name="newline" match="newline|line-break|br">
		<latex><xsl:text> \\
</xsl:text></latex>
		<html><BR/></html>
	</template>

	<!-- Whereas newline|line-break is for line breaks intended to be outputted in the final document, this is for additional linebreaks in the generated latex or HTML source (for stuff like avoiding "\end{verbatim}\item" all on one line). -->
	<template name="newline-internal" match="newline-internal">
		<latex><xsl:text>
</xsl:text></latex>
		<html><xsl:text>
</xsl:text></html>
	</template>
	
	<template name="page-break" match="page-break|new-page|newpage|pagebreak">
		<latex>\newpage</latex>
	</template>
	
	<!--
		Insert a space. Useful for the occaisional case where two
		elements occur next to each other with only a space separating
		them (e.g., an <emph> immediately following a <quote>), and the
		space gets gobbled by XSLT, producing leading to non-separated
		words in the output. It doesn't seem very consistent as to when
		it does and doesn't happen, unfortunately, but when it does
		happen, inserting a <space/> will fix the problem.

		This is analogous to putting a \ at the end of macros in LaTeX
		to ensure that spaces after the macro aren't gobbled, and indeed,
		this is what the LaTeX version of the markup produces.
	-->
	<template name="space" match="space">
		<html><xsl:text> </xsl:text></html>
		<latex><xsl:text>\ </xsl:text></latex>
	</template>

	<template name="non-breaking-space" match="non-breaking-space|nbsp">
		<latex>~</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text></html>
	</template>

	<!--
		Technically we don't need to disable output escaping for all of
		these, but it's probably better to code them all consistently,
		rather than trying to figure out which ones do need it (e.g.,
		&#160; for a non-breaking space) and which ones don't (e.g.,
		&amp;).
	-->
	<template name="ellipsis-sign" match="ellipsis-sign|etc|ellipsis|dots">
		<latex>{\ldots}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8230;</xsl:text></html>
	</template>

	<!-- Misc typographic symbols -->
	<template name="endash" match="endash|en-dash">	
		<latex>--</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8211;</xsl:text></html>
	</template>

	<template name="emdash" match="emdash|em-dash">
		<latex>---</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8212;</xsl:text></html>
	</template>
	
	<!-- Use this for literal underscores that appear outside code blocks. Such things cause LaTeX to wig out. -->
	<template name="underscore" match="underscore">
		<latex>\_</latex>
		<html>_</html>
	</template>

	<template name="apostrophe" match="apostrophe">
		<latex>'</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8217;</xsl:text></html>
	</template>

	<template name="dollar" match="dollar|dollar-sign">
		<latex>{\$}</latex>
		<html>$</html>
	</template>

	<template name="percent-sign" match="percent-sign|percentage-sign|percent">
		<latex>{\%}</latex>
		<html>%</html>
	</template>

	<template name="ampersand" match="ampersand">
		<latex>{\&amp;}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;amp;</xsl:text></html>
	</template>

	<template name="trademark-sign" match="trademark-sign|trademark|TM">
		<latex>{\texttrademark}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8482;</xsl:text></html>
	</template>

	<template name="copyright-sign" match="copyright-sign">
		<latex>{\copyright}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#169;</xsl:text></html>
	</template>

	<template name="degree-sign" match="degree-sign|degrees">
		<latex>\ensuremath{^{\circ}}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#176;</xsl:text></html>
	</template>

	<template name="section-sign" match="section-sign">
		<latex>{\S}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#167;</xsl:text></html>
	</template>

	<template name="sharp-sign" match="sharp|hash">
		<latex>{\#}</latex>
		<html><xsl:text>#</xsl:text></html>
	</template>

	<template name="paragraph-sign" match="paragraph-sign">
		<latex>{\P}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#182;</xsl:text></html>
	</template>

	<!-- I think the pi symbol is only available in LaTeX in math mode, but if we're already in math mode, the extra $ signs will mess things up... -->
	<!-- Use \ensuremath to resolve the problem. -->
	<template name="pi" match="pi|project">
		<latex>\ensuremath{\pi}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#960;</xsl:text></html>
	</template>
	<template name="sigma" match="sigma|restrict">
		<latex>\ensuremath{\sigma}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#963;</xsl:text></html>
	</template>
	<template name="rho" match="rho|rename">
		<latex>\ensuremath{\rho}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#961;</xsl:text></html>
	</template>

	<template name="element-sign" match="element-sign|element|element-of|is-element-of|is-an-element-of">
		<latex>\ensuremath{\in}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8712;</xsl:text></html>
	</template>
	
	<template name="not-element-sign" match="not-element-sign|not-element|not-element-of|is-not-element-of|is-not-an-element-of">
		<latex>\ensuremath{\not\in}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8713;</xsl:text></html>
	</template>
	
	<template name="subset-sign" match="subset-sign|subset|subset-of|is-subset-of|is-a-subset-of">
		<latex>\ensuremath{\subset}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8834;</xsl:text></html>
	</template>

	<template name="superset-sign" match="superset-sign|superset|superset-of|is-superset-of|is-a-superset-of">
		<latex>\ensuremath{\supset}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8835;</xsl:text></html>
	</template>

	<template name="join-operator" match="join-operator|join|natural-join">
		<latex>\ensuremath{\Join}</latex>
		<!--
			No easy way at present to get the join symbol in HTML, so
			just use an image. Scale it to 10x10 pixels (fine as long as
			font size is set relatively normally).
			
			We need to ensure that the path is absolute, becuase we don't
			necessarily know where the document will end up in the tree.
		-->
		<html>
			<IMG>
				<xsl:attribute name="SRC">
					<xsl:text>/</xsl:text>
					<xsl:value-of select="$department"/>
					<xsl:value-of select="$paper"/>
					<xsl:text>/Handbook/Graphics/join-operator-96dpi.png</xsl:text>
				</xsl:attribute>
				<xsl:attribute name="ALT">
					<xsl:text>Join operator</xsl:text>
				</xsl:attribute>
				<xsl:attribute name="WIDTH">
					<xsl:text>10</xsl:text>
				</xsl:attribute>
				<xsl:attribute name="HEIGHT">
					<xsl:text>10</xsl:text>
				</xsl:attribute>
				<xsl:attribute name="STYLE">
					<xsl:text>padding-left:0.3em;padding-right:0.3em</xsl:text>
				</xsl:attribute>
			</IMG>
		</html>
	</template>

	<template name="intersect-operator" match="intersect-operator|intersect|intersection|cap">
		<latex>\ensuremath{\cap}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8745;</xsl:text></html>
	</template>

	<template name="union-operator" match="union-operator|union|cup">
		<latex>\ensuremath{\cup}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8746;</xsl:text></html>
	</template>

	<template name="logical-and-operator" match="logical-and|and|and-operator|hat|wedge">
		<latex>\ensuremath{\wedge}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8743;</xsl:text></html>
	</template>

	<template name="logical-or-operator" match="logical-or|or|or-operator|vee">
		<latex>\ensuremath{\vee}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8744;</xsl:text></html>
	</template>

	<template name="LaTeX" match="LaTeX|latex">
		<latex>{\LaTeX}</latex>
		<html>L<SUP>A</SUP>T<SUB>E</SUB>X</html>
	</template>

	<!-- Note: no equivalent of \triangleright in HTML, use right arrow instead. -->
	<template name="menu-separator" match="menu-separator|menusep|menu/separator">
		<latex> \ensuremath{\triangleright} </latex>
		<html><xsl:text disable-output-escaping="yes"> &amp;#8594; </xsl:text></html>
	</template>

	<template name="menu-item" match="menu/item">
		<latex>\textbf{<xsl:apply-templates/>}</latex>
		<html><B><xsl:apply-templates/></B></html>
	</template>
	
	<!-- Special styles -->
	<template name="emph" match="emph|em">
		<latex>\emph{<xsl:apply-templates/>}</latex>
		<html><EM><xsl:apply-templates/></EM></html>
	</template>
	<!--
		Emphasis inside answers needs to be handled specially in HTML, as
		it doesn't just flip-flop automatically like it does in LaTeX.
	-->
	<template name="emph-in-answer" match="answer//emph|answer//em">
		<latex>\emph{<xsl:apply-templates/>}</latex>
		<html><STRONG><xsl:apply-templates/></STRONG></html>
	</template>
	<template name="italic" match="italic">
		<latex>\textit{<xsl:apply-templates/>}</latex>
		<html><I><xsl:apply-templates/></I></html>
	</template>
	<template name="strong" match="strong">
		<latex>\textbf{<xsl:apply-templates/>}</latex>
		<html><STRONG><xsl:apply-templates/></STRONG></html>
	</template>
	<template name="bold" match="bold">
		<latex>\textbf{<xsl:apply-templates/>}</latex>
		<html><B><xsl:apply-templates/></B></html>
	</template>
	<template name="underline" match="underline|u">
		<latex>\underline{<xsl:apply-templates/>}</latex>
		<html><U><xsl:apply-templates/></U></html>
	</template>
	<template name="term" match="term">
		<latex>\term{<xsl:apply-templates/>}</latex>
		<html><I CLASS="term"><xsl:apply-templates/></I></html>
	</template>
	<template name="foreign" match="foreign">
		<latex>\foreign{<xsl:apply-templates/>}</latex>
		<html><I CLASS="foreign"><xsl:apply-templates/></I></html>
	</template>
	<template name="code" match="code">
		<!-- <latex>\code{<xsl:apply-templates/>}</latex> -->
		<!-- Using \verb is quite handy because things like underscores don't bother it.  However, it seems it can't be used inside hyperlinks.   Maybe create another template that just does a \texttt on the contents? -->
		<!-- OK, but then we need an <underscore> element to stop them from freaking LaTeX out. -->
		<latex>\verb`<xsl:apply-templates/>`</latex>
		<html><CODE><xsl:apply-templates/></CODE></html>
	</template>

	<template name="typewriter" match="typewriter|monospace|tt">
		<latex>\texttt{<xsl:apply-templates/>}</latex>
		<html><TT><xsl:apply-templates/></TT></html>
	</template>
	
	<template name="sans-serif" match="sans-serif|sans|ss|sf">
		<latex>\textsf{<xsl:apply-templates/>}</latex>
		<html><FONT FACE="sans-serif"><xsl:apply-templates/></FONT></html>
	</template>
	
	<!-- Non-maths super- and subscript. -->
	<template name="superscript" match="superscript">
		<latex>\ensuremath{^{\mathrm{<xsl:apply-templates/>}}}</latex>
		<html><SUP><xsl:apply-templates/></SUP></html>
	</template>
	
	<template name="subscript" match="subscript">
		<latex>\ensuremath{_{\mathrm{<xsl:apply-templates/>}}}</latex>
		<html><SUB><xsl:apply-templates/></SUB></html>
	</template>
	
	<!--
		Text that shouldn't be broken across a line (i.e., LaTeX \mbox).
		Only really relevant for LaTeX because we can't control this in HTML.
	-->
	<template name="no-break" match="no-break|mbox">
		<latex>\mbox{<xsl:apply-templates/>}</latex>
		<html><xsl:apply-templates/></html>
	</template>
	
	
	<!--
		Skip a certain amount of space vertically.
		Probably more relevant to LaTeX than HTML.
		Is it even possible to vskip a set amount in HTML??
		
		@size: the amount of space to skip.
			missing => \vskip\baselineskip [default]
			'small' => \smallskip
			'medium' => \medskip
			'large' => \bigskip
			'fill' => \vfill
			LaTeX length => \vskipxx
	-->
	<template name="vertical-skip" match="vertical-skip|vskip">
		<latex>
			<xsl:choose>
				<xsl:when test="not(@size)">
					\vskip\baselineskip
				</xsl:when>
				<xsl:when test="@size='small'">
					\smallskip
				</xsl:when>
				<xsl:when test="@size='medium'">
					\medskip
				</xsl:when>
				<xsl:when test="@size='large'">
					\bigskip
				</xsl:when>
				<xsl:when test="@size='fill'">
					\vfill
				</xsl:when>
				<xsl:otherwise>
					\vskip<xsl:value-of select="@size"/>
				</xsl:otherwise>
			</xsl:choose>
		</latex>
		<!-- For the moment we'll just throw in a BR :) -->
		<html><BR/></html>
	</template>
	

	<!-- We can decide later whether to use plain verbatim or listings. -->
	<template name="code-block" match="code-block">
		<latex>
			<xsl:call-template name="newline-internal"/>
			<!-- If the code-block specifies "allow-breaks='no'", wrap the verbatim inside a minipage to avoid page breaks within the code. -->
			<xsl:if test="@allow-breaks = 'no'">
				<xsl:text>\vskip\baselineskip</xsl:text>
				<xsl:call-template name="newline-internal"/>
				<xsl:text>\begin{minipage}{\textwidth}</xsl:text>
				<xsl:call-template name="newline-internal"/>
			</xsl:if>
			<xsl:text>\begin{verbatim}</xsl:text>
			<xsl:apply-templates/>
			<xsl:text>\end{verbatim}</xsl:text>
			<xsl:call-template name="newline-internal"/>
			<xsl:if test="@allow-breaks = 'no'">
				<xsl:text>\end{minipage}</xsl:text>
				<xsl:call-template name="newline-internal"/>
				<xsl:text>\vskip\baselineskip</xsl:text>
				<xsl:call-template name="newline-internal"/>
			</xsl:if>
		</latex>
		<html>
			<PRE CLASS="code"><xsl:apply-templates/></PRE>
		</html>
	</template>

	<!--
		This is for stuff that should unequivocally be treated verbatim (e.g. problem code).
		I'm pretty sure that previously this was distinguished from "code-block" because it (code-block) used to use listings instead of verbatim.  Now that they're both using verbatim there is probably no need for them both (but we might switch back to using listings for code-block).
	-->
	<template name="verbatim" match="verbatim">
		<latex>
			<xsl:call-template name="newline-internal"/>
			<xsl:text>\begin{verbatim}</xsl:text>
			<xsl:apply-templates/>
			<xsl:text>\end{verbatim}</xsl:text>
			<xsl:call-template name="newline-internal"/>
		</latex>
		<html>
			<PRE><xsl:apply-templates/></PRE>
		</html>
	</template>

	
	<!--
		Quoted text. Handles nested quotes correctly.
		
		@single: Whether to enclose the text in single or double quotes.
			'yes' => single quotes ('').
			otherwise => double quotes (""). [default]
	-->
	<template name="single-quote" match="quote[@single='yes']|q[@single='yes']">
		<latex>`<xsl:apply-templates/>'</latex>
		<html>
			<xsl:text disable-output-escaping="yes">&amp;#8216;</xsl:text>
			<xsl:apply-templates/>
			<xsl:text disable-output-escaping="yes">&amp;#8217;</xsl:text>
		</html>
	</template>
	<template name="double-quote" match="quote|qq">
		<latex>``<xsl:apply-templates/>''</latex>
		<html>
			<xsl:text disable-output-escaping="yes">&amp;#8220;</xsl:text>
			<xsl:apply-templates/>
			<xsl:text disable-output-escaping="yes">&amp;#8221;</xsl:text>
		</html>
	</template>
	<!--
		With nested quotes, we need to figure out what depth of nesting
		we're at, then call the appropriate template depending on
		the initial quoting style (single or double).
	-->
	<template name="nested-double-quote" match="quote//quote">
		<common>
			<xsl:choose>
				<xsl:when test="(count(ancestor::quote) mod 2) = 0">
					<xsl:call-template name="double-quote"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:call-template name="single-quote"/>
				</xsl:otherwise>
			</xsl:choose>
		</common>
	</template>
	<template name="nested-single-quote" match="quote[@single='yes']//quote" priority="2">
		<common>
			<xsl:choose>
				<xsl:when test="(count(ancestor::quote) mod 2) = 0">
					<xsl:call-template name="single-quote"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:call-template name="double-quote"/>
				</xsl:otherwise>
			</xsl:choose>
		</common>
	</template>


	<!-- Environments (in the LaTeX terminology): enumerated, ordered, and numbered lists. -->

	<!-- Unordered lists -->
	
	<template name="itemised-list" match="itemised-list|itemize|unordered-list|bulleted-list|bullet-list|bullet-points|UL|ul">
		<latex>
			\begin{itemize}
				<xsl:apply-templates select="item" mode="normal"/>
			\end{itemize}
			
		</latex>
		<html>
			<UL>
				<xsl:apply-templates select="item" mode="normal"/>
			</UL>
		</html>
	</template>
	

	<!-- Ordered lists -->
	
	<template name="enumerated-list" match="enumerated-list|enumerate|ordered-list|numbered-list|question-list|OL|ol">
		<latex>
			\begin{enumerate}
				<xsl:apply-templates select="item" mode="normal"/>
			\end{enumerate}
			
		</latex>
		<html>
			<OL>
				<xsl:apply-templates select="item" mode="normal"/>
			</OL>
		</html>
	</template>
	
	
	<!-- Definition or description lists. -->
	<template name="definition-list" match="definition-list|description-list|DL|dl">
		<latex>
			\begin{description}
				<xsl:apply-templates select="item" mode="definition-list"/>
			\end{description}
			
		</latex>
		<html>
			<!--
				<DL>s in HTML tend to come out with the spacing a bit
				wrong (or maybe it's just my browser?). Anyway, they
				don't appear to be displayed correctly. A more portable
				solution is to use plain <P>s with CSS margins to
				control the hanging indent. The tricky part is dealing
				with embedded <paragraph>s inside the
				<description-list>. The clever details are handled in
				the "definition-item" template.
			-->
			<xsl:apply-templates select="item" mode="definition-list"/>
		</html>
	</template>


	<!-- List elements -->
	<template name="list-item" match="item" mode="normal">
		<latex><xsl:text>\item </xsl:text><xsl:apply-templates/></latex>
		<html>
			<xsl:choose>
				<!--
					Check whether there are actual paragraphs or things that
					should be treated like paragraphs inside the item. If so,
					let them worry about inserting the <P> tags.
					
					I've added include-document to the list to stop
					included questions from having extra <p>'s wrapped
					around them. This seems to work and should be a
					sensible approach; since you can't predict what an
					included document might do, it's safer to let it
					worry about paragraphs. However, I'm not sure what
					implications this decision might have in general. A
					longer-term solution would be to move to something
					that supports XInclude, but this is probably too new
					yet?
				-->
				<xsl:when test="count(paragraph|para|p|question|answer|code-block|include-document) != 0">
					<LI><xsl:apply-templates/></LI>
				</xsl:when>
				<!--
					Otherwise, insert <P> tags surrounding the item content
					so that the item spacing looks OK.
				-->
				<xsl:otherwise>
					<LI><P><xsl:apply-templates/></P></LI>
				</xsl:otherwise>
			</xsl:choose>
		</html>
	</template>

	<template name="definition-item" match="item" mode="definition-list">
		<latex>
			<xsl:text>\item[</xsl:text>
			<xsl:apply-templates select="keyword|topic|DT|dt"/>
			<xsl:text>] </xsl:text>
			<xsl:apply-templates select="definition|description|discourse|DD|dd"/>
		</latex>
		<html>
			<!--
				We have to be a little clever here, because we're
				transforming potentially multiple embedded elements
				(embedded <paragraph>s in particular) into one or more
				<P> tags in the HTML. We need to ensure that:
				
					(a) we don't end up with nested <P> tags,
					    
					(b) all paragraphs are correctly indented, and
					
					(c) if the first thing following the <definition>
						is a <paragraph> or text node, it gets
						positioned correctly relative to the <keyword>.

				We know that the <keyword> won't have embedded
				<paragraph>s (it doesn't really make sense, not that we
				actually check :)  The only thing we therefore need to
				check for is <paragraph> elements inside the
				<definition> element.
			-->
			<xsl:choose>
				<!--
					If the first sub-node of the <definition> is a text
					node, then the whole thing should be just simple
					text and contain only basic formatting elements, if
					anything (i.e., no lists!). We therefore just wrap
					the <keyword> and <definition> within a <P> with a
					hanging indent and finish. Note the use of
					child::node[1|2], because we don't necessarily know
					what variants of <keyword> and <definition> have
					actually been used, but we know that they will
					(should!) always be the first and second children of
					the <item> respectively.
					
					This probably is the most common case, so test for
					it first.
				-->
				<xsl:when test="not(name(child::node()[2]/node()[1]))">
					<P CLASS="definition1">
						<xsl:apply-templates select="child::node()[1]"/>
						<xsl:text> </xsl:text>
						<xsl:apply-templates select="child::node()[2]"/>
					</P>
				</xsl:when>
				<!--
					If the first sub-node of the <definition> is a <p>
					or <paragraph>, then we need to skip over the
					processing of this element to avoid nested <P>s in
					the output. Any remaining sub-nodes are processed
					normally, except that we pass in the HTMLStyle
					parameter to ensure that any remaining paragraph
					elements are correctly indented. I would have used
					modes for this, but it killed embedded <itemize>s,
					because there isn't an <itemize> template with the
					appropriate mode (nor is there a need for one). Grr.
				-->
				<xsl:when test="child::node()[2]/child::node()[1][self::p] or child::node()[2]/child::node()[1][self::paragraph]">
					<P CLASS="definition1">
						<xsl:apply-templates select="child::node()[1]"/>
						<xsl:text> </xsl:text>
						<xsl:apply-templates select="child::node()[2]/child::node()[1]/node()"/>
					</P>
					<xsl:apply-templates select="child::node()[2]/*[position() > 1]">
						<xsl:with-param name="HTMLStyle">definition2</xsl:with-param>
					</xsl:apply-templates>
				</xsl:when>
				<!--
					In all other cases, dump out the keyword in its own
					paragraph, then zip through the list of sub-nodes
					and process them normally, with the addition of the
					HTMLStyle parameter, as noted above.
					
					If there are more than one, wrap the <keyword> and
					the first <paragraph> of the <definition> in a
					hanging <P>, then wrap the remainder in indented,
					non-hanging <P>s.
				-->
				<xsl:otherwise>
					<P CLASS="definition1">
						<xsl:apply-templates select="child::node()[1]"/>
					</P>
					<xsl:apply-templates select="child::node()[2]/node()">
						<xsl:with-param name="HTMLStyle">definition2</xsl:with-param>
					</xsl:apply-templates>
				</xsl:otherwise>
			</xsl:choose>
		</html>
	</template>
	
	<template name="keyword" match="keyword|topic|DT|dt">
		<latex><xsl:apply-templates/></latex>
		<html><STRONG><xsl:apply-templates/></STRONG></html>
	</template>
	
	
	<!--
		Need to provide some context here as, e.g., <description> is also
		used within <image>.
	-->
	<template name="definition" match="item/definition|item/description|item/discourse|item/DD|item/dd">
		<common><xsl:apply-templates/></common>
	</template>


	<!--
		Question text. This only exists so that we can ensure that appropriate
		<P> tags are correctly inserted. If this template didn't exist, showing
		the answers would generate invalid HTML. The answers are enclosed in a
		<DIV CLASS="answer">...</DIV>. Without this template, the answer markup
		ends up embedded inside <P>...</P>, which is invalid.
	-->
	<template name="question" match="question">
		<latex><xsl:apply-templates/></latex>
		<html>
			<xsl:choose>
				<!--
					Check whether there are actual paragraphs inside the
					question. If so, let them worry about inserting the
					<P> tags.
					
					I've added include-document to the list to stop
					included questions from having extra <p>'s wrapped
					around them. This seems to work and should be a
					sensible approach; since you can't predict what an
					included document might do, it's safer to let it
					worry about paragraphs. However, I'm not sure what
					implications this decision might have in general. A
					longer-term solution would be to move to something
					that supports XInclude, but this is probably too new
					yet?
				-->
				<xsl:when test="count(paragraph|para|p|question|answer|code-block|include-document) != 0">
					<xsl:apply-templates/>
				</xsl:when>
				<!--
					Otherwise, insert <P> tags surrounding the question content.
				-->
				<xsl:otherwise>
					<P><xsl:apply-templates/></P>
				</xsl:otherwise>
			</xsl:choose>
		</html>
	</template>

	
	<!--
		Sample answers, which may optionally be excluded from the
		output. This can be done globally for all answers by setting the
		style sheet parameter $showanswers to "no", or it can be done
		locally on a question-by-question basis by setting the @hide
		attribute of the element to "yes".
		
		@hide: If "yes", don't include this answer in the output stream.
		The default is to include the answer.
	-->
	<template name="answer" match="answer">
		<latex>
			<!--
				It's nice to weed out the sample answer markup at the XSLT processing stage to make LaTeX run faster.
				Note that \showanswers still needs to be called so that LaTeX can format chapter headings like "Answers for ..."
			-->
			<xsl:if test="$showanswers='yes'">
			\begin{answer}
				<xsl:apply-templates/>
			\end{answer}

			</xsl:if>
		</latex>
		<html>
			<xsl:if test="$showanswers='yes'">
				<DIV CLASS="answer">
					<xsl:apply-templates/>
				</DIV>
			</xsl:if>
		</html>
	</template>
	
	<!--
		Match hidden answers and do nothing.
	-->
	<template name="hidden-answer" match="answer[@hide='yes']"/>

	
	<!--
		Sections, subsections, subsubsections, ...
		
		@label: A label that can be used for cross referencing. Any
		value can be used, as long as it's a legal identifier in both
		LaTeX and HTML.
	-->
	<template name="section" match="section">
		<latex>
			<xsl:apply-templates>
				<xsl:with-param name="label">
					<xsl:value-of select="@label"/>
					<xsl:if test="not(@label)">THERE_IS_NO_LABEL</xsl:if>
				</xsl:with-param>
			</xsl:apply-templates>
		</latex>
		<html>
			<xsl:if test="@label"><A NAME="{@label}"></A></xsl:if>
			<xsl:apply-templates/>
		</html>
	</template>
	
	
	<!-- Footnotes. -->
	<template name="footnote" match="footnote">
		<latex>\footnote{<xsl:apply-templates/>}</latex>
		<html>
			<A>
				<xsl:attribute name="NAME">
					<xsl:text>footnote-</xsl:text>
					<xsl:number level="any" count="footnote"/>
					<xsl:text>-source</xsl:text>
				</xsl:attribute>
				<xsl:attribute name="HREF">
					<xsl:text>#footnote-</xsl:text>
					<xsl:number level="any" count="footnote"/>
					<xsl:text>-target</xsl:text>
				</xsl:attribute>
				<xsl:text>[</xsl:text>
				<xsl:number level="any" count="footnote"/>
				<xsl:text>]</xsl:text>
			</A>
		</html>
	</template>

	<!-- This is only required for HTML, as LaTeX does it all for you. -->
	<template name="footnote-list" match="footnote" mode="list">
		<html>
			<P>
				<A>
					<xsl:attribute name="NAME">
						<xsl:text>footnote-</xsl:text>
						<xsl:number level="any" count="footnote"/>
						<xsl:text>-target</xsl:text>
					</xsl:attribute>
					<xsl:text>[</xsl:text>
					<xsl:number level="any" count="footnote"/>
					<xsl:text>]</xsl:text>
				</A>
				<xsl:text> </xsl:text>
				<xsl:apply-templates/>
				<xsl:text> </xsl:text>
				<!-- Provide a back link to the original footnote marker. -->
				<A>
					<xsl:attribute name="HREF">
						<xsl:text>#footnote-</xsl:text>
						<xsl:number level="any" count="footnote"/>
						<xsl:text>-source</xsl:text>
					</xsl:attribute>
					<xsl:text>[Back]</xsl:text>
				</A>
			</P>
		</html>
	</template>

	
	<!-- Document preamble stuff: title, author, date. -->
	<template name="preamble-title" match="document/title" mode="preamble">
		<latex>\title{<xsl:apply-templates/>}</latex>
		<!--
			For HTML, strip out any formatting (e.g., emphasis), as this
			is not interpreted within the <TITLE> tag, resulting in raw
			HTML markup in the window title. Ick. We do this by just
			grabbing the values of all descendant text nodes.
		-->
		<html><xsl:value-of select="."/></html>
	</template>

	<template name="preamble-author" match="document/author" mode="preamble">
		<latex>\author{<xsl:apply-templates/>}</latex>
	</template>

	<template name="preamble-date" match="document/date" mode="preamble">
		<latex>\date{<xsl:apply-templates/>}</latex>
	</template>

	<template name="document-title" match="document/title">
		<!-- Need to do something sensible for LaTeX here. -->
		<latex>
			<!-- Under the LaTeX framework, the rest of the chapter title text is generated by LaTeX macros, so this is pretty simple. -->
			<!-- I think this is broken? -->
			<xsl:if test="/document/@standalone = 'yes'"><xsl:apply-templates/></xsl:if>
		</latex>
		<html>
			<H1>
				<xsl:choose>
					<xsl:when test="/document/@class = 'tutorial'">
						<xsl:if test="$showanswers='yes'">Selected Answers for </xsl:if>
						<xsl:call-template name="PaperCode"/>
						<xsl:text> Tutorial </xsl:text>
						<xsl:value-of select="/document/@sequence-number"/>
						<xsl:text>: </xsl:text>
						<BR/>
					</xsl:when>
					<xsl:when test="/document/@class = 'laboratory'">
						<xsl:if test="$showanswers='yes'">Selected Answers for </xsl:if>
						<xsl:call-template name="PaperCode"/>
						<xsl:text> Lab </xsl:text>
						<xsl:value-of select="/document/@sequence-number"/>
						<xsl:text>: </xsl:text>
						<BR/>
					</xsl:when>
				</xsl:choose>
				<xsl:apply-templates/>
			</H1>
		</html>
	</template>

	<!-- New template for tutorials and labs, which are essentially chapters when included in a course book, but are marked up as documents in themselves. -->
	<template name="chapter-title" match="document/title" mode="chapter">
		<latex>
			<xsl:apply-templates/>
		</latex>
		<html>
			<xsl:choose>
				<xsl:when test="/document/@class = 'tutorial'">
					<H1><xsl:call-template name="PaperCode"/> Tutorial <xsl:value-of select="/document/@sequence-number"/><xsl:if test="$showanswers='yes'"> Sample Answers</xsl:if>: <BR/><xsl:apply-templates/></H1>
				</xsl:when>
				<xsl:when test="/document/@class = 'laboratory'">
					<H1><xsl:call-template name="PaperCode"/> Lab <xsl:value-of select="/document/@sequence-number"/><xsl:if test="$showanswers='yes'"> Sample Answers</xsl:if>: <BR/><xsl:apply-templates/></H1>
				</xsl:when>
				<xsl:otherwise>
					<H1><xsl:apply-templates/></H1>
				</xsl:otherwise>
			</xsl:choose>
		</html>
	</template>
	
	<template name="document-author" match="document/author"/>
	<template name="document-date" match="document/date"/>

	<!--
		Generate some number of "sub"s so we can produce, e.g.,
		"subsubsection" for LaTeX.
		
		$depth: the number of repetitions (0 <= $depth <= 2, but there's
		no need to do bounds checking at the upper end, because that's
		already dealt with in the "section-title" template below).
	-->
	<template name="generate-subs">
		<latex>
			<xsl:param name="depth">1</xsl:param>
			<xsl:if test="$depth &gt; 1">
				<xsl:text>sub</xsl:text>
				<xsl:call-template name="generate-subs">
					<xsl:with-param name="depth"><xsl:value-of select="$depth - 1"/></xsl:with-param>
				</xsl:call-template>
			</xsl:if>
		</latex>
	</template>
	
	<!-- Generate section title with nested numbering, e.g., 1.1.3. -->
	<template name="section-title" match="section/title">
		<latex>
			<xsl:param name="label"/>
			<xsl:text>\</xsl:text>
			<!-- Generate the correct number of "sub"s for LaTeX. -->
			<xsl:call-template name="generate-subs">
				<xsl:with-param name="depth">
					<xsl:number value="count(ancestor::section)"/>
					<xsl:if test="count(ancestor::section) &gt; 3">3</xsl:if>
				</xsl:with-param>
			</xsl:call-template>
			<xsl:text>section{</xsl:text>
			<xsl:apply-templates/><xsl:text>}</xsl:text>
			<xsl:if test="$label != 'THERE_IS_NO_LABEL'">
				\label{<xsl:value-of select="$label"/>}
			</xsl:if>
		</latex>
		<html>
			<!-- The depth is used in a couple of places, so we pre-calculate it. -->
			<xsl:variable name="depth">
				<xsl:number value="1 + count(ancestor::section)"/>
				<xsl:if test="1 + count(ancestor::section) &gt; 6">6</xsl:if>
			</xsl:variable>
			<xsl:text disable-output-escaping="yes">&lt;H</xsl:text><xsl:number value="$depth"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
			<xsl:number count="section" level="multiple" format="1.1.1.1.1.1"/>
			<xsl:text> </xsl:text>
			<xsl:apply-templates/>
			<xsl:text disable-output-escaping="yes">&lt;/H</xsl:text><xsl:number value="$depth"/><xsl:text disable-output-escaping="yes">&gt;</xsl:text>
		</html>
	</template>


	<!--
		A quotation.
		
		@align: The alignment of the quotation paragraph.
			'left' [default]
			'center'
			'right'
	-->
	<template name="quotation" match="quotation">
		<latex>
			<xsl:choose>
				<xsl:when test="(@align = 'left') or (@align = 'right')">
					<xsl:text>\begin{flush</xsl:text>
					<xsl:value-of select="@align"/>
					<xsl:text>}\itshape </xsl:text>
					<xsl:apply-templates/>
					<xsl:text>\end{flush</xsl:text>
					<xsl:value-of select="@align"/>
					<xsl:text>}</xsl:text>
				</xsl:when>
				<xsl:when test="@align = 'center'">
					<xsl:text>\begin{center}\itshape </xsl:text>
					<xsl:apply-templates/>
					<xsl:text>\end{center}</xsl:text>
				</xsl:when>
				<xsl:otherwise>
					<xsl:text>\begin{quote}\itshape </xsl:text>
					<xsl:apply-templates/>
					<xsl:text>\end{quote}</xsl:text>
				</xsl:otherwise>
			</xsl:choose>
		</latex>
		<!-- Nominally we should use <BLOCKQUOTE>, but it doesn't have alignment. -->
		<html>
			<P>
				<xsl:if test="@align">
					<xsl:attribute name="ALIGN">
						<xsl:value-of select="@align"/>
					</xsl:attribute>
				</xsl:if>
				<I><xsl:apply-templates/></I>
			</P>
		</html>
	</template>
	
	
	<!--
		Anything inside a <metadata> is ignored completely. (More
		accurately, we pick bits out of it manually as required; it's
		only ignored by apply-templates.)

		If we move to using attributes of "document" for all metadata, this will become redundant.
	-->
	<template name="metadata" match="metadata">
		<common>
			<xsl:message><xsl:text>Use of metadata element obsolete!</xsl:text></xsl:message>
		</common>
	</template>
	
	
	<!--
		Anything inside an <omit> is also ignored completely.
	-->
	<template name="omit" match="omit"/>

	<!--
		...and the legacy id tags inside figures.
	-->
	<template match="figure/id"/>
	<template match="figure/label"/>

	
	<!--
		Comments are not quite ignored completely, as they're carried through to the output document (kind of: "It is an error if instantiating the content of xsl:comment creates nodes other than text nodes.")
	-->
	<template name="comment" match="comment">
		<latex>
			<xsl:text>
\begin{comment}</xsl:text>
				<xsl:apply-templates/>
				<xsl:text>\end{comment}
</xsl:text>
		</latex>
		<html>
			<xsl:comment>
				<xsl:apply-templates/>
			</xsl:comment>
		</html>
	</template>
	
	
	<!--
		Tabular structures (LaTeX {tabular}, HTML <TABLE>).
		
		@align: The alignment of the table as a whole.
			'left' [default]
			'center'
			'right'
		
		@valign (LaTeX only): Vertical alignment of the tabular within
		the paragraph. 
			'top'
			'center' [default]
			'bottom'
		
		@border: Width of cell border for HTML tables.
		
		@scale (LaTeX only): Scaling factor for the tabular.
		
		@rotate (LaTeX only): Rotation angle of tabular in degrees
		anti-clockwise.
	-->
	<template name="tabular" match="tabular">
		<latex>
			<!-- spacing -->
			<xsl:text>
			
			</xsl:text>
			
			<!-- Overall tabular alignment. -->
			<xsl:if test="@align">
				<xsl:text>\begin{</xsl:text>
				<xsl:choose>
					<xsl:when test="(@align = 'left') or (@align = 'right')">
						<xsl:text>flush</xsl:text><xsl:value-of select="@align"/>
					</xsl:when>
					<xsl:when test="@align = 'center'">
						<xsl:text>center</xsl:text>
					</xsl:when>
				</xsl:choose>
				<xsl:text>}</xsl:text>
			</xsl:if>

			<!-- tabular rotation -->
			<xsl:if test="@rotate">
				<xsl:text>\rotatebox{</xsl:text>
				<xsl:value-of select="@rotate"/>
				<xsl:text>}{</xsl:text>
			</xsl:if>

			<!-- tabular scaling -->
			<xsl:if test="@scale">
				<xsl:text>\scalebox{</xsl:text>
				<xsl:value-of select="@scale"/>
				<xsl:text>}{</xsl:text>
			</xsl:if>

			<xsl:text>\begin{tabular}</xsl:text>
			<!-- vertical alignment -->
			<xsl:if test="@valign = 'top' or @valign = 'bottom'">
				<xsl:text>[</xsl:text>
				<xsl:value-of select="substring(@valign, 1, 1)"/>
				<xsl:text>]</xsl:text>
			</xsl:if>
			<xsl:text>{</xsl:text>
			<xsl:apply-templates select="tabular-columns"/>
			<xsl:text>}</xsl:text>
				<xsl:apply-templates select="tabular-header"/>
				<xsl:apply-templates select="tabular-body"/>
				<xsl:apply-templates select="tabular-footer"/>
			<xsl:text>\end{tabular}</xsl:text>

			<xsl:if test="@scale"><xsl:text>}</xsl:text></xsl:if>

			<xsl:if test="@rotate"><xsl:text>}</xsl:text></xsl:if>

			<xsl:if test="@align">
				<xsl:text>\end{</xsl:text>
				<xsl:choose>
					<xsl:when test="(@align = 'left') or (@align = 'right')">
						<xsl:text>flush</xsl:text><xsl:value-of select="@align"/>
					</xsl:when>
					<xsl:when test="@align = 'center'">
						<xsl:text>center</xsl:text>
					</xsl:when>
				</xsl:choose>
				<xsl:text>}</xsl:text>
			</xsl:if>

			<!-- spacing -->
			<xsl:text>

			</xsl:text>
		</latex>
		<html>
			<TABLE>
				<xsl:attribute name="BORDER">
					<xsl:value-of select="@border"/>
					<xsl:if test="not(@border)">0</xsl:if>
				</xsl:attribute>
				<xsl:if test="@align">
					<xsl:attribute name="ALIGN">
						<xsl:value-of select="@align"/>
					</xsl:attribute>
				</xsl:if>
				<!--
					Note different ordering of tabular components:
					HTML requires THEAD and TFOOT to precede TBODY.
				-->
				<xsl:apply-templates select="tabular-header"/>
				<xsl:apply-templates select="tabular-footer"/>
				<xsl:apply-templates select="tabular-body"/>
			</TABLE>
		</html>
	</template>
	
	<!--
		Specify column formatting, mainly for LaTeX, although
		HTML does get <TD> ALIGN values from here.
		
		@align: The alignment of this particular column.
			'left' [default]
			'center'
			'right'
		
		@left-border: Set to '|' to include a column separator to the
		left of this column.

		@right-border: Set to '|' to include a column separator to the
		right of this column.
		
		Careful: including a right-border on a cell and a left-border on
		the next cell will produce '||', not '|'. BUT, when doing
		multi-column or multi-row cells, always include both borders if
		required, because \multicolumn overrides the default border
		specification.
	-->
	<template name="aligned-tabular-column" match="tabular-columns/column[@align]">
		<latex>
			<xsl:value-of select="@left-border"/>
			<xsl:value-of select="substring(@align, 1, 1)"/>
			<xsl:value-of select="@right-border"/>
		</latex>
	</template>

	<template name="unaligned-tabular-column" match="tabular-columns/column[not(@align)]">
		<latex>
			<xsl:value-of select="@left-border"/>
			<xsl:text>l</xsl:text>
			<xsl:value-of select="@right-border"/>
		</latex>
	</template>
	
	<template name="tabular-header" match="tabular-header">
		<latex></latex>
		<html>
			<THEAD>
				<xsl:apply-templates/>
			</THEAD>
		</html>
	</template>

	<template name="tabular-footer" match="tabular-footer">
		<latex></latex>
		<html>
			<TFOOT>
				<xsl:apply-templates/>
			</TFOOT>
		</html>
	</template>

	<template name="tabular-body" match="tabular-body">
		<latex><xsl:apply-templates/></latex>
		<html>
			<TBODY>
				<xsl:apply-templates/>
			</TBODY>
		</html>
	</template>

	<!--
		@no-page-break: Inhibit page breaks after this row (LaTeX only).
	-->
	<template name="row" match="row">
		<latex>
			<xsl:apply-templates/>
			<!-- TODO: Don't put a \\ on the last row of a tabular. -->
			<xsl:text> \\</xsl:text>
			<xsl:if test="@no-page-break = 'yes'">*</xsl:if>
			<xsl:text> </xsl:text>
		</latex>
		<html>
			<TR>
				<xsl:if test="@valign">
					<xsl:attribute name="VALIGN"><xsl:value-of select="@valign"/></xsl:attribute>
				</xsl:if>
				<xsl:apply-templates/>
			</TR>
		</html>
	</template>

	<!--
		Horizontal rules (LaTeX only).
		
		@columns: The column range to draw the rule across. Specify as
		you would for a \cline in LaTeX, e.g., '3-5'. If omitted, the
		rule is drawn across all columns.
	-->
	<template name="row-rule-full" match="row-rule[not(@columns)]">
		<latex><xsl:text>\hline </xsl:text></latex>
	</template>

	<template name="row-rule-partial" match="row-rule[@columns]">
		<latex>\cline{<xsl:value-of select="@columns"/>}</latex>
	</template>
	
	<!--
		Hmm, the multi-row stuff is somewhat broken in LaTeX, oops.
		Need to insert missing columns (as was done in the calendar
		XSL) when a multi-row cell is encountered.
		
		Also need to sort out \hlines in the presence of multi-row cells
		and also what happens to vertical cell borders :(
		
		This probably needs reworking.
	-->
	
	<!--
		Multi-row cells (LaTeX only, as this is pretty trivial to
		achieve in HTML).
		
		@rows: The number of rows this cell spans.
		@header: Is this a header cell? [yes, NO]
	-->
	<template name="multirow-cell" match="cell" mode="latex-multi-row">
		<latex>
			<xsl:text>\multirow{</xsl:text>
			<xsl:value-of select="@rows"/>
			<xsl:text>}{*}{</xsl:text>
			<xsl:if test="@header = 'yes'"><xsl:text>\textbf{</xsl:text></xsl:if>

			<!-- check for embedded line breaks, if so, embed another tabular inside this one -->
			<xsl:if test="count(child::br) != 0">
				<xsl:text>\begin{tabular}{@{}</xsl:text>
				<xsl:choose>
					<xsl:when test="@align">
						<xsl:value-of select="substring(@align, 1, 1)"/>
					</xsl:when>
					<xsl:otherwise>
						<xsl:text>l</xsl:text>
					</xsl:otherwise>
				</xsl:choose>
				<xsl:text>@{}}</xsl:text>
			</xsl:if>

			<xsl:apply-templates/>

			<xsl:if test="count(child::br) != 0">
				<xsl:text>\end{tabular}
			</xsl:text></xsl:if>
			<xsl:if test="@header = 'yes'"><xsl:text>}</xsl:text></xsl:if>
			<xsl:text>}</xsl:text>
		</latex>
	</template>
	
	<!--
		Multi-column cells (LaTeX only, as this is pretty trivial to
		achieve in HTML).
		
		$num-columns: The number of rows this cell spans.
		@header: Is this a header cell? [yes, NO]
	-->
	<template name="multicolumn-cell" match="cell" mode="latex-multi-column">
		<latex>
			<xsl:param name="num-columns">1</xsl:param>
			<xsl:text>\multicolumn{</xsl:text>
			<xsl:value-of select="$num-columns"/>
			<xsl:text>}{</xsl:text>
			<xsl:value-of select="@left-border"/>
			<xsl:choose>
				<xsl:when test="@align">
					<xsl:value-of select="substring(@align, 1, 1)"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:text>l</xsl:text>
				</xsl:otherwise>
			</xsl:choose>
			<xsl:value-of select="@right-border"/>
			<xsl:text>}{</xsl:text>
			<xsl:choose>
				<xsl:when test="@rows">
					<xsl:apply-templates select="." mode="multi-row"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:if test="@header = 'yes'"><xsl:text>\textbf{</xsl:text></xsl:if>

					<!-- check for embedded line breaks, if so, embed another tabular inside this one -->
					<xsl:if test="count(child::br) != 0">
						<xsl:text>\begin{tabular}{@{}</xsl:text>
						<xsl:choose>
							<xsl:when test="@align">
								<xsl:value-of select="substring(@align, 1, 1)"/>
							</xsl:when>
							<xsl:otherwise>
								<xsl:text>l</xsl:text>
							</xsl:otherwise>
						</xsl:choose>
						<xsl:text>@{}}</xsl:text>
					</xsl:if>

					<xsl:apply-templates/>

					<xsl:if test="count(child::br) != 0">
						<xsl:text>\end{tabular}
					</xsl:text></xsl:if>
					<xsl:if test="@header = 'yes'"><xsl:text>}</xsl:text></xsl:if>
				</xsl:otherwise>
			</xsl:choose>
			<xsl:text>}</xsl:text>
		</latex>
	</template>
	
	<!--
		Top-level template for generating cells.
		
		@columns: The number of columns this cell spans.
		@rows: The number of rows this cell spans.
		@align: The alignment of this cell. [LEFT, center, right]
		@header: Is this a header cell? [yes, NO]
	-->
	<template match="cell">
		<common>
			<!-- position() doesn't seem to work very well in this context. -->
			<xsl:variable name="column-no"><xsl:number/></xsl:variable>
		</common>
		<!--
			Doing this sensibly for LaTeX is actually pretty ugly,
			because different attribute combinations produce different
			code :(
			
			This is the sort of algorithm that can only really be
			clearly described by a flow chart :)
		-->
		<latex>
			<xsl:choose>
				<xsl:when test="@columns">
					<xsl:apply-templates select="." mode="latex-multi-column">
						<xsl:with-param name="num-columns" select="@columns"/>
					</xsl:apply-templates>
				</xsl:when>
				<xsl:when test="@align">
					<xsl:apply-templates select="." mode="latex-multi-column"/>
				</xsl:when>
				<xsl:when test="@rows">
					<xsl:apply-templates select="." mode="latex-multi-row"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:if test="@header = 'yes'"><xsl:text>\textbf{</xsl:text></xsl:if>

					<!-- check for embedded line breaks, if so, embed another tabular inside this one -->
					<xsl:if test="count(child::br) != 0">
						<xsl:text>\begin{tabular}{@{}</xsl:text>
						<xsl:choose>
							<xsl:when test="@align">
								<xsl:value-of select="substring(@align, 1, 1)"/>
							</xsl:when>
							<xsl:otherwise>
								<xsl:text>l</xsl:text>
							</xsl:otherwise>
						</xsl:choose>
						<xsl:text>@{}}</xsl:text>
					</xsl:if>

					<xsl:apply-templates/>

					<xsl:if test="count(child::br) != 0">
						<xsl:text>\end{tabular}
					</xsl:text></xsl:if>
					<xsl:if test="@header = 'yes'"><xsl:text>}</xsl:text></xsl:if>
				</xsl:otherwise>
			</xsl:choose>
			<xsl:if test="$column-no != last()"> &amp; </xsl:if>
		</latex>
		<!--
			It's much easier in HTML, because a <TD> is a <TD> is a
			<TD>, regardless of the attributes supplied.
		-->
		<html>
			<!--
				Hmm, how to generate either a TD or TH as required,
				including attributes, without repeating code?
				
				Aha, the answer is attribute value templates!
			-->
			<xsl:variable name="celltype">
				<xsl:choose>
					<xsl:when test="@header = 'yes'">TH</xsl:when>
					<xsl:otherwise>TD</xsl:otherwise>
				</xsl:choose>
			</xsl:variable>
			<xsl:element name="{$celltype}">
				<xsl:attribute name="ALIGN">
					<xsl:value-of select="@align"/>
					<xsl:if test="not(@align)">
						<xsl:value-of select="ancestor::tabular/tabular-columns/column[position() = $column-no]/@align"/>
						<xsl:if test="not(ancestor::tabular/tabular-columns/column[position() = $column-no]/@align)">left</xsl:if>
					</xsl:if>
				</xsl:attribute>
				<xsl:attribute name="VALIGN">
					<xsl:value-of select="@valign"/>
					<xsl:if test="not(@valign)">middle</xsl:if>
				</xsl:attribute>
				<xsl:attribute name="COLSPAN">
					<xsl:value-of select="@columns"/>
					<xsl:if test="not(@columns)">1</xsl:if>
				</xsl:attribute>
				<xsl:attribute name="ROWSPAN">
					<xsl:value-of select="@rows"/>
					<xsl:if test="not(@rows)">1</xsl:if>
				</xsl:attribute>
				<xsl:apply-templates/>
			</xsl:element>
		</html>
	</template>
	
	
	<!--
		Hyperlinks. The content of the element is the hyperlink text.
		
		@label: A label that the hyperlink links to. The value should
		be an acceptable label in both LaTeX and HTML. [optional]
		
		@url: A URL that the hyperlink links to. If no link text is
		provided, the URL is used as the link text. [optional]
	-->
	<template name="hyperlink-label" match="hyperlink[@label]">
		<latex>\hyperref[<xsl:value-of select="@label"/>]{<xsl:apply-templates/>}</latex>
		<html><A HREF="#{@label}"><xsl:apply-templates/></A></html>
	</template>

	<template name="hyperlink-url" match="hyperlink[@url and node()]">
		<latex>\href{<xsl:value-of select="@url"/>}{<xsl:apply-templates/>}</latex>
		<html><A HREF="{@url}"><xsl:apply-templates/></A></html>
	</template>

	<!-- Internal parameterised hyperlink template to be called by the likes of the empty Oracle documentation elements. -->
	<template name="hyperlink-internal" match="hyperlink" mode="hyperlink-internal">
		<common>
			<xsl:param xmlns:xsl-out="http://www.w3.org/1999/XSL/Transform" name="url"/>
			<xsl:param xmlns:xsl-out="http://www.w3.org/1999/XSL/Transform" name="label"/>
		</common>
		<latex>\href{<xsl:value-of select="$url"/>}{<xsl:apply-templates select="exsl:node-set($label)"/>}</latex>
		<html><A HREF="{$url}"><xsl:apply-templates select="exsl:node-set($label)"/></A></html>
	</template>

	<template name="empty-hyperlink-url" match="hyperlink[@url and not(node())]">
		<!-- Note: not safe to use the url package here because \url{...} is fragile. -->
		<latex>\href{<xsl:value-of select="@url"/>}{\texttt{<xsl:value-of select="@url"/>}}</latex>
		<html><A HREF="{@url}"><CODE><xsl:value-of select="@url"/></CODE></A></html>
	</template>
	
	<!-- A plain URL (i.e., not necessarily a hyperlink). -->
	<template name="url" match="url|uri|email|e-mail|email-address|e-mail-address">
		<!--
			Hmm, \url{...} appears to turn the URL into a non-functional
			link in PDF output (probably an interaction with hyperref).
			Not really what we want (as the link aspect is already dealt
			with by the <hyperlink> templates), so we'll just use
			\texttt{...}.
		-->
		<latex>\texttt{<xsl:apply-templates/>}</latex>
		<html><CODE><xsl:apply-templates/></CODE></html>
	</template>
	


	<!--
		References. Note the distinction betwen these and hyperlinks: a
		reference is merely something like "see Section 2.3", and
		doesn't necessarily imply a hyperlink, or vice versa.
		
		@label: The label of the item that we're referencing. It must be
		a valid label in both LaTeX and HTML. [required]
	-->
	<template name="reference" match="reference">
		<common>
			<!-- Find the element whose label is the same as our label. -->
			<xsl:apply-templates select="//*[@label = current()/@label]" mode="reference"/>
		</common>
	</template>
	
	<!-- Do a separate template for each type of reference; easier. -->
	<template name="section-reference" match="section" mode="reference">
		<!-- It's probably more consistent to just use \ref* and insert "Section" ourselves rather than let LaTeX do it. -->
		<latex>Section~\ref*{<xsl:value-of select="@label"/>}</latex>
		<html>
			<xsl:text disable-output-escaping="yes">Section&amp;#160;</xsl:text>
			<xsl:number count="section" level="multiple" format="1.1.1.1.1.1"/>
		</html>
	</template>
	
	<template name="figure-reference" match="figure" mode="reference">
		<latex>Figure~\ref*{<xsl:value-of select="@label"/>}</latex>
		<html>
			<xsl:text disable-output-escaping="yes">Figure&amp;#160;</xsl:text>
			<xsl:choose>
				<xsl:when test="$showanswers='yes'">
					<xsl:number count="figure" level="any" format="1"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:number count="figure[not(ancestor::answer) and not(ancestor::omit) and not(ancestor::comment)]" level="any" format="1"/>
				</xsl:otherwise>
			</xsl:choose>
		</html>
	</template>
	
	<template name="table-reference" match="table" mode="reference">
		<latex>Table~\ref*{<xsl:value-of select="@label"/>}</latex>
		<html>
			<xsl:text disable-output-escaping="yes">Table&amp;#160;</xsl:text>
			<xsl:choose>
				<xsl:when test="$showanswers='yes'">
					<xsl:number count="table" level="any" format="1"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:number count="table[not(ancestor::answer) and not(ancestor::omit) and not(ancestor::comment)]" level="any" format="1"/>
				</xsl:otherwise>
			</xsl:choose>
		</html>
	</template>
	
	
	<!-- Figures & tables (in the LaTeX sense, i.e., "floating" items). -->
	<template name="figure" match="figure">
		<latex>
			\begin{figure}<xsl:if test="@latex-placement">[<xsl:value-of select="@latex-placement"/>]</xsl:if>
				\centering
				<xsl:apply-templates select="*[not(self::caption)]"/>
				<xsl:if test="count(caption) != 0">
					\caption{<xsl:apply-templates select="caption"/>}
					<xsl:if test="@label">\label{<xsl:value-of select="@label"/>}</xsl:if>
					<xsl:if test="count(id) != 0">\label{<xsl:value-of select="id"/>}</xsl:if>
				</xsl:if>
			\end{figure}
		</latex>
		<html>
			<DIV CLASS="figure">
				<CENTER>
					<xsl:if test="@label"><A NAME="{@label}"></A></xsl:if>
					<xsl:if test="count(id) != 0"><A NAME="{id}"></A></xsl:if>
					<xsl:apply-templates select="*[not(self::caption)]"/>
					<xsl:if test="count(caption) != 0">
						<BR/>
						<xsl:apply-templates select="caption"/>
					</xsl:if>
				</CENTER>
			</DIV>
		</html>
	</template>
	
	<template name="table" match="table">
		<latex>
			\begin{table}<xsl:if test="@latex-placement">[<xsl:value-of select="@latex-placement"/>]</xsl:if>
				\centering
				<xsl:apply-templates select="*[not(self::caption)]"/>
				<xsl:if test="count(caption) != 0">
					\caption{<xsl:apply-templates select="caption"/>}
					<xsl:if test="@label">\label{<xsl:value-of select="@label"/>}</xsl:if>
				</xsl:if>
			\end{table}
		</latex>
		<html>
			<DIV CLASS="table">
				<CENTER>
					<xsl:if test="@label"><A NAME="{@label}"></A></xsl:if>
					<xsl:apply-templates select="*[not(self::caption)]"/>
					<xsl:if test="count(caption) != 0">
						<BR/>
						<xsl:apply-templates select="caption"/>
					</xsl:if>
				</CENTER>
			</DIV>
		</html>
	</template>
	
	<template name="multipart-table" match="table[count(part) &gt; 0]">
		<latex>
			<xsl:for-each select="part">
				\begin{table}[p]
					\centering
					<xsl:apply-templates/>
					<xsl:if test="count(../caption) != 0">
						<xsl:text>\caption{</xsl:text>
						<xsl:apply-templates select="../caption"/>
						<xsl:choose>
							<xsl:when test="position() &gt; 1">
								<xsl:text> \emph{(continued)}}</xsl:text>
							</xsl:when>
							<xsl:otherwise>
								<xsl:text> \emph{(continues over)}}</xsl:text>
								<xsl:if test="../@label">\label{<xsl:value-of select="../@label"/>}</xsl:if>
							</xsl:otherwise>
						</xsl:choose>
						<!-- Consider the possibility of labels for each part? -->
						<!-- <xsl:if test="@label">\label{<xsl:value-of select="@label"/>}</xsl:if> -->
					</xsl:if>
				\end{table}
				\addtocounter{table}{-1}
				\clearpage
			</xsl:for-each>
			\stepcounter{table}
		</latex>
	</template>
	
	<template name="figure-caption" match="figure/caption">
		<latex><xsl:apply-templates/></latex>
		<html>
			<STRONG>
				<xsl:text>Figure </xsl:text>
				<xsl:choose>
					<xsl:when test="$showanswers='yes'">
						<xsl:number count="figure" level="any" format="1"/>
					</xsl:when>
					<xsl:otherwise>
						<xsl:number count="figure[not(ancestor::answer) and not(ancestor::omit) and not(ancestor::comment)]" level="any" format="1"/>
					</xsl:otherwise>
				</xsl:choose>
				<xsl:text>. </xsl:text>
			</STRONG>
			<xsl:apply-templates/>
		</html>
	</template>
	
	<template name="table-caption" match="table/caption">
		<latex><xsl:apply-templates/></latex>
		<html>
			<STRONG>
				<xsl:text>Table </xsl:text>
				<xsl:choose>
					<xsl:when test="$showanswers='yes'">
						<xsl:number count="table" level="any" format="1"/>
					</xsl:when>
					<xsl:otherwise>
						<xsl:number count="table[not(ancestor::answer) and not(ancestor::omit) and not(ancestor::comment)]" level="any" format="1"/>
					</xsl:otherwise>
				</xsl:choose>
				<xsl:text>. </xsl:text>
			</STRONG>
			<xsl:apply-templates/>
		</html>
	</template>
	
	
	<!--
		Images. Includes a scaling factor for LaTeX.
		
		To do: alternatively, allow defining the scaling factor by specifying what proportion of the page width the image should occupy (a la LaTeX [width] parameter).
		How about a <latex-attributes> element that can be used to specify \includegraphics arguments?
			<width keepaspectratio="yes">0.5\columnwidth</width>
			<height>2cm</height>
			<scale>0.5</scale>
			etc.
		
		To do: if no description is given, use the basename as the content of the ALT element.
		Ideally, I think we should be able to define two image formats (PDF, EPS, PNG, ...) when marking up an image: one for LaTeX output, another for HTML.  Mind you, if the generation of the various formats from a single master is handled outside of the XSLT processing...?
	-->
	
	<!-- LaTeX images are always handled the same way regardless. -->
	<template match="image" mode="latex">
		<latex>
			<xsl:text>\includegraphics</xsl:text>
			<xsl:if test="count(latex-scaling) != 0">
				<xsl:message terminate="no">&lt;latex-scaling&gt; element is deprecated in &lt;image&gt;; please use latex-options attribute instead.</xsl:message>
				<xsl:text>[scale=</xsl:text>
				<xsl:value-of select="latex-scaling"/>
				<xsl:text>]</xsl:text>
			</xsl:if>
			<!-- Adding general-purpose latex pass-through arguments for \includegraphics; this should eventually subsume the "scale"-only handler above. -->
			<!-- If providing multiple arguments, these should be comma-separated in the source XML, but no not need the enclosing square brackets. -->
			<xsl:if test="@latex-options">
				<xsl:text>[</xsl:text>
				<xsl:value-of select="@latex-options"/>
				<xsl:text>]</xsl:text>
			</xsl:if>
			<xsl:text>{</xsl:text>
			<!--
				Work out the full path specification for the file
				to be included = base-path + location + basename.
			-->
			<xsl:value-of select="$base-path"/>
			<xsl:text>/</xsl:text>			

			<!-- Use whatever standard image folder is appropriate for the context. -->
			<xsl:choose>
				<!-- Could possibly change this to test="/document/@class = 'tutorial'" or similar? -->
				<!-- Sounds nicer...I think ideally the XSL processor would automatically figure out the path to the graphics based on the path to the source XML file.  Can this be done? -->
				<xsl:when test="name(/child::node()[1])='tutorial' or /document/@class = 'tutorial' or name(/child::node()[1])='laboratory' or /document/@class = 'laboratory'">
					<xsl:text>Graphics</xsl:text>
				</xsl:when>
				<!-- Allow the author to specify a non-standard image location on the fly. -->
				<xsl:when test="@location">
					<xsl:value-of select="@location"/>
				</xsl:when>
				<!-- new style in progress... -->
				<xsl:otherwise>
					<xsl:text>images</xsl:text>
				</xsl:otherwise>
			</xsl:choose>
			<xsl:text>/</xsl:text>

			<!-- need to phase out "basename" as an element and switch to using an attribute -->
			<xsl:if test="count(basename) != 0">
				<xsl:message terminate="no">&lt;basename&gt; element is deprecated in &lt;image&gt;; please use basename attribute instead.</xsl:message>
				<xsl:value-of select="basename"/>
			</xsl:if>
			<xsl:if test="@basename">
				<xsl:value-of select="@basename"/>
			</xsl:if>
			<xsl:text>.</xsl:text>
			
			<!-- Figure out the image format. -->
			<xsl:choose>
				<xsl:when test="count(format) != 0">
					<xsl:message terminate="no">&lt;format&gt; element is deprecated in &lt;image&gt;; please use basename attribute instead.</xsl:message>
					<xsl:value-of select="format"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="$image-format"/>
				</xsl:otherwise>
			</xsl:choose>
			<xsl:text>}</xsl:text>
		</latex>
	</template>
	
	<template match="image[count(provide-large-version) = 0]">
		<latex><xsl:apply-templates select="." mode="latex"/></latex>
		<html>
			<IMG CLASS="padded" BORDER="0">
				<xsl:attribute name="SRC">
					<xsl:choose>
						<xsl:when test="(name(/child::node()[1])='tutorial') or (name(/child::node()[1])='laboratory') or /document/@class = 'tutorial' or /document/@class = 'laboratory' ">
							<xsl:text>Graphics/</xsl:text>
							<xsl:value-of select="basename|@basename"/>
							<xsl:text>-96dpi</xsl:text>
						</xsl:when>
						<!-- Allow the author to specify a non-standard image location on the fly. -->
						<xsl:when test="@location">
							<xsl:value-of select="@location"/>
							<xsl:text>/</xsl:text>
							<xsl:value-of select="basename|@basename"/>
						</xsl:when>
						<xsl:otherwise>
							<xsl:text>images/</xsl:text>
							<xsl:value-of select="basename|@basename"/>
						</xsl:otherwise>
					</xsl:choose>
					<xsl:text>.</xsl:text>
					<xsl:choose>
						<!-- CME: oops, I'd originally used the "format" tag to identify the format used in the LaTeX version, not the HTML! -->
						<xsl:when test="count(format) != 0">
							<xsl:message terminate="no">&lt;format&gt; element is deprecated in &lt;image&gt;; please use basename attribute instead.</xsl:message>
							<xsl:value-of select="format"/>
						</xsl:when>
						<xsl:otherwise>
							<xsl:text>png</xsl:text>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:attribute>
				<xsl:attribute name="ALT"><xsl:apply-templates select="description"/></xsl:attribute>
			</IMG>
		</html>
	</template>

	<template match="image[count(provide-large-version) != 0]">
		<latex><xsl:apply-templates select="." mode="latex"/></latex>
		<html>
			<A>
				<xsl:attribute name="HREF">
					<!-- This first bit needs to be updated to match the rest, particularly
					     with regards to non-standard image directories.
					-->
					<xsl:text>images/</xsl:text>
					<xsl:value-of select="basename|@basename"/>
					<xsl:text>-zoom.</xsl:text>
					<xsl:choose>
						<xsl:when test="count(format) != 0">
							<xsl:value-of select="format"/>
						</xsl:when>
						<xsl:otherwise>
							<xsl:text>png</xsl:text>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:attribute>
				<IMG CLASS="padded" BORDER="0">
					<xsl:attribute name="SRC">
						<xsl:choose>
							<xsl:when test="(name(/child::node()[1])='tutorial') or (name(/child::node()[1])='laboratory') or /document/@class = 'tutorial' or /document/@class = 'laboratory' ">
								<xsl:text>Graphics/</xsl:text>
								<xsl:value-of select="basename|@basename"/>
								<xsl:text>-96dpi</xsl:text>
							</xsl:when>
							<!-- Allow the author to specify a non-standard image location on the fly. -->
							<xsl:when test="@location">
								<xsl:value-of select="@location"/>
								<xsl:text>/</xsl:text>
								<xsl:value-of select="basename|@basename"/>
							</xsl:when>
							<xsl:otherwise>
								<xsl:text>images/</xsl:text>
								<xsl:value-of select="basename|@basename"/>
							</xsl:otherwise>
						</xsl:choose>
						<xsl:text>.</xsl:text>
						<xsl:choose>
							<!-- CME: oops, I'd originally used the "format" tag to identify the format used in the LaTeX version, not the HTML! -->
							<xsl:when test="count(format) != 0">
								<xsl:message terminate="no">&lt;format&gt; element is deprecated in &lt;image&gt;; please use basename attribute instead.</xsl:message>
								<xsl:value-of select="format"/>
							</xsl:when>
							<xsl:otherwise>
								<xsl:text>png</xsl:text>
							</xsl:otherwise>
						</xsl:choose>
					</xsl:attribute>
					<xsl:attribute name="ALT">
						<xsl:apply-templates select="description"/>
					</xsl:attribute>
				</IMG>
				<BR CLEAR="right"/>
				<xsl:text>(Larger version)</xsl:text>
			</A>
		</html>
	</template>
	
	
	<!--
		Include another XML/HTML/LaTeX document into the current one. If
		you don't specify @type, it assumes the type of document that
		you're currently generating (HTML or LaTeX).
		
		LaTeX documents are simply included using \input{...}. The old
		<latex-input> element is now deprecated.

		HTML documents are a little trickier, as there's no equivalent
		of \input{} in HTML, plus the XSLT processor always seems to
		generate a DOCTYPE when producing HTML, whether you want it or
		not, which means that you can only really include entire HTML
		documents, rather than HTML fragments (maybe you can turn this
		off?). The workaround currently is to embed the HTML document
		inside an <OBJECT>.

		A similar argument applies for plain text documents (such as
		code listings) that we want to include, but are externally
		generated and so can't just be embedded in the source XML.

		@type: The type of the document to be included. [optional] Valid
		values are:
			"xml"
			"html" [default for HTML]
			"latex" [default for LaTeX]
			"text"
		
		@basename: Name of file to include (including suffix!).
		[required]
		
		@location: Path to file to include. Note that this gets a /
		appended to it. However, this shouldn't make any difference in
		normal usage. [optional]
	-->
	<template name="include-document" match="include-document">
		<common>
			<!--
				Work out the full path specification for the file
				to be included = base-path + location + basename.
			-->
			<xsl:variable name="file">
				<xsl:value-of select="$base-path"/>
				<xsl:text>/</xsl:text>			
				<xsl:if test="@location">
					<xsl:value-of select="@location"/>
					<xsl:text>/</xsl:text>
				</xsl:if>
				<xsl:value-of select="@basename"/>
			</xsl:variable>
		</common>
		<html>
			<DIV>
				<xsl:attribute name="ALIGN">
					<xsl:choose>
						<xsl:when test="@align"><xsl:value-of select="@align"/></xsl:when>
						<xsl:otherwise>LEFT</xsl:otherwise>
					</xsl:choose>
				</xsl:attribute>
				
				<OBJECT DATA="{$file}">
					<!-- Output text/html or text/plain as appropriate. -->
					<xsl:attribute name="TYPE">
						<xsl:text>text/</xsl:text>
						<xsl:choose>
							<xsl:when test="@type"><xsl:value-of select="@type"/></xsl:when>
							<xsl:otherwise><xsl:text>html</xsl:text></xsl:otherwise>
						</xsl:choose>
					</xsl:attribute>
					<xsl:attribute name="WIDTH">
						<xsl:choose>
							<xsl:when test="@width"><xsl:value-of select="@width"/></xsl:when>
							<xsl:otherwise><xsl:text>100%</xsl:text></xsl:otherwise>
						</xsl:choose>
					</xsl:attribute>
					<xsl:attribute name="HEIGHT">
						<xsl:choose>
							<xsl:when test="@height"><xsl:value-of select="@height"/></xsl:when>
							<xsl:otherwise><xsl:text>100%</xsl:text></xsl:otherwise>
						</xsl:choose>
					</xsl:attribute>
				</OBJECT>
			</DIV>
		</html>
		<latex>
			<xsl:text>\</xsl:text>
			<!--
				Note that input text files are currently verbatim'd in
				LaTeX. We may want to change this in future?
			-->
			<xsl:if test="@type = 'text'">
				<xsl:text>verbatim</xsl:text>
			</xsl:if>
			<xsl:text>input{</xsl:text>
			<xsl:value-of select="$file"/>
			<xsl:text>}</xsl:text>
		</latex>
	</template>
	
	<template name="include-xml" match="include-document[@type='xml']">
		<common>
			<xsl:variable name="file">
				<xsl:value-of select="$base-path"/>
				<xsl:text>/</xsl:text>
				<xsl:if test="@location">
					<xsl:value-of select="@location"/>
					<xsl:text>/</xsl:text>
				</xsl:if>
				<xsl:value-of select="@basename"/>
			</xsl:variable>
			<xsl:apply-templates select="document($file,/)"/>
		</common>
	</template>
	

	<!--
		Environment setup. This enables you to define environment settings
		(e.g., required LaTeX packages, etc.). We normally explicitly call
		the sub-elements within this, so this template is empty to prevent
		unwanted stuff accidentally being included in the output.
	-->
	<template name="environment" match="environment"/>

	<!--
		Load a LaTeX package.
		
		@options: Any arguments to the package. [optional]
	-->
	<template name="latex-package" match="latex-packages/package">
		<latex>\usepackage<xsl:if test="@options">[<xsl:value-of select="@options"/>]</xsl:if>{<xsl:value-of select="."/>}</latex>
	</template>
		
	<!--
		Execute a preamble LaTeX command. Use to set up things like
		counters, fonts, hyperref options, etc.
	-->
	<template name="latex-command" match="latex-commands/command">
		<latex><xsl:value-of select="."/></latex>
	</template>
	

	<!--
		Hmm, the following may be more complex than I thought...
		External environment files sort of stuff it up. Perhaps
		LaTeX document class stuff should be in attributes of the
		document element?
	-->
	<!--
		Specify LaTeX document class and options. The master stylesheet
		specifies \documentclass[a4paper,12pt]{article}. Anything you
		specify here will override that completely, so be sure to set
		a4paper and 12pt if that's what you want.
		
		@options: The required document class options. [optional]
	-->
	<template name="latex-documentclass" match="latex-documentclass|documentclass">
		<latex>\documentclass{<xsl:value-of select="."/>}</latex>
	</template>
	<template name="latex-documentclass-options" match="latex-documentclass[@options]|documentclass[@options]">
		<latex>\documentclass[<xsl:value-of select="@options"/>]{<xsl:value-of select="."/>}</latex>
	</template>
	
	<!--
		Specify additional LaTeX document class options (i.e., in
		addition to the defaults). These should be a comma-separated
		list of the required options. These will be appended to the
		standard defaults (a4paper, 12pt).
	-->
	<template name="latex-document-options" match="latex-document-options">
		<latex><xsl:apply-templates/></latex>
	</template>
	
	
	<!-- Sometimes we might need to embed raw code to handle something tricky. -->
	<template name="raw-latex" match="raw-code[@format = 'latex']|raw-latex">
		<latex><xsl:apply-templates/></latex>
	</template>
		
	<template name="raw-html" match="raw-code[@format = 'html']|raw-html">
		<html><xsl:copy-of select="*"/></html>
	</template>
		
	<!-- Generate a LaTeX \input{} macro. -->
	<template name="latex-input" match="latex-input">
		<latex>
			<xsl:message>Use of latex-input is deprecated. Please use include-document instead.</xsl:message>
			\input{<xsl:value-of select="."/>}
		</latex>
	</template>

	
	<!--
		Conditional processing depending on the format. It may appear
		redundant to have two templates, but this is the only way to
		ensure that the LaTeX template is empty in the HTML style sheet,
		and vice versa.
		
		@format: the format under which this XML is to be processed.
		[required]
	-->
	<template name="process-when-latex" match="process-when[@format = 'latex']">
		<latex><xsl:apply-templates/></latex>
	</template>
	
	<template name="process-when-html" match="process-when[@format = 'html']">
		<html><xsl:apply-templates/></html>
	</template>
	
	
	<!--
		Basic maths stuff. Anything more complicated is... complicated.
		We should probably be using MathML, but we still have to mangle
		it into HTML regardless.
		
		@style: How to format the maths expression. Valid values are:
			'inline' [default] display expression inline
			'display' display expression in its own paragraph
	-->
	<template name="math-inline" match="math|math[@style='inline']">
		<latex>\(<xsl:apply-templates/>\)</latex>
		<html><xsl:apply-templates/></html>
	</template>
	
	<template name="math-display" match="math[@style='display']">
		<latex>\[<xsl:apply-templates/>\]</latex>
		<html><P ALIGN="center"><xsl:apply-templates/></P></html>
	</template>

	
	<!-- Equation arrays -->
	
	<template name="equation-array" match="equation-array">
		<latex>
			<xsl:text>\begin{eqnarray*}
</xsl:text>
			<xsl:apply-templates/>
			<xsl:text>\end{eqnarray*}</xsl:text>
		</latex>
		<html>
			<TABLE CLASS="equation" BORDER="0" ALIGN="CENTER"><xsl:apply-templates/></TABLE>
		</html>
	</template>


	<!-- Hmm, LaTeX uses "&" as separators: how do we know if there's another cell coming?  Ah, but the LaTeX eqnarray can have no more than three columns, so there's no need to generalise. -->
	<template match="equation-array/row">
		<latex>
			<xsl:apply-templates select="left"/><xsl:text disable-output-escaping="yes">	&amp;	</xsl:text><xsl:apply-templates select="middle"/><xsl:text disable-output-escaping="yes">	&amp;	</xsl:text><xsl:apply-templates select="right"/><xsl:text>	\\
\\
</xsl:text>
		</latex>
		<html>
			<TR><TD ALIGN="RIGHT"><xsl:apply-templates select="left"/></TD><TD ALIGN="CENTER"><xsl:apply-templates select="middle"/></TD><TD ALIGN="LEFT"><xsl:apply-templates select="right"/></TD></TR>
		</html>
	</template>
	

	<!-- Roman (upright) text inside math environments.  \mathrm sounds like it's probably more correct, but doesn't retain spaces (which \textup does). -->
	<template name="math-text" match="text">
		<latex>\textup{<xsl:apply-templates/>}</latex>
		<html><xsl:apply-templates/></html>
	</template>
	
	<!--
		Calligraphic letters (upper case only for LaTeX).
	-->
	<template name="calligraphic-text" match="calligraphic|cursive">
		<latex>\ensuremath{\mathcal{<xsl:apply-templates/>}}</latex>
		<html><FONT FACE="cursive"><xsl:apply-templates/></FONT></html>
	</template>
	
	<!-- Digit grouping separator character for large numbers.  SI conventions say this should be a space (but we could make it a comma if desired). -->
	<template name="digit-group-separator" match="digit-group-separator|digitsep">
		<html><xsl:call-template name="non-breaking-space"/></html>
		<latex><xsl:text>\,</xsl:text></latex>
	</template>

	<!-- Mathematical super- and subscript. -->
	<template name="superscript-math" match="math//superscript">
		<latex>\ensuremath{^{<xsl:apply-templates/>}}</latex>
		<html><SUP><xsl:apply-templates/></SUP></html>
	</template>
	
	<template name="subscript-math" match="math//subscript">
		<latex>\ensuremath{_{<xsl:apply-templates/>}}</latex>
		<html><SUB><xsl:apply-templates/></SUB></html>
	</template>
	
	<!--
		Basic mathematical operators.
		
		We get around the problem of math vs. non-math mode
		operators in LaTeX by liberally sprinkling \ensuremath
		around. If we're not in math mode, it enables it, and if
		we're already in math mode, it ignores it. This means we
		don't need identical templates for math and non-math modes. Yay!

		Do we really need <left-parenthesis> and <right-parenthesis>?
		Maybe we're getting a little carried away with these :)
	-->
	<template name="plus-operator" match="plus">
		<common>+</common>
	</template>
	
	<template name="minus-operator" match="minus">
		<latex>\ensuremath{-}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8722;</xsl:text></html>
	</template>
	
	<template name="times-operator" match="times">
		<latex>\ensuremath{\times}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#215;</xsl:text></html>
	</template>
	
	<template name="divide-operator" match="divide">
		<common>/</common>
	</template>
	
	<template name="equals-operator" match="equals">
		<!-- Need spaces for HTML as they seem to get munched otherwise. -->
		<common>=</common>
	</template>

	<template name="greater-than-operator" match="greater-than|gt">
		<!-- Need spaces for HTML as they seem to get munched otherwise. -->
		<latex> \ensuremath{&gt;} </latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#62;</xsl:text></html>
	</template>

	<template name="greater-equals-operator" match="greater-equals|ge">
		<!-- Need spaces for HTML as they seem to get munched otherwise. -->
		<latex> \ensuremath{\geq} </latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8805;</xsl:text></html>
	</template>

	<template name="less-than-operator" match="less-than|lt">
		<!-- Need spaces for HTML as they seem to get munched otherwise. -->
		<latex> \ensuremath{&lt;} </latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#60;</xsl:text></html>
	</template>

	<template name="less-equals-operator" match="less-equals|le">
		<!-- Need spaces for HTML as they seem to get munched otherwise. -->
		<latex> \ensuremath{\leq} </latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8804;</xsl:text></html>
	</template>

	<template name="approximately-equals-operator" match="approximately-equals|approximately-equal-to|approx">
		<latex>\ensuremath{\approx}</latex>
		<html><xsl:text disable-output-escaping="yes">&amp;#8776;</xsl:text></html>
	</template>
	
	<template name="right-arrow" match="right-arrow|rightarrow|implies|rarr|rarrow">
		<latex>
			<xsl:text> \ensuremath{\</xsl:text>
			<xsl:choose>
				<xsl:when test="@weight='double'">R</xsl:when>
				<xsl:otherwise>r</xsl:otherwise>
			</xsl:choose>
			<xsl:text>ightarrow} </xsl:text>
		</latex>
		<html>
			<xsl:choose>
				<xsl:when test="@weight='double'">
					<xsl:text disable-output-escaping="yes">&amp;#8658;</xsl:text>
				</xsl:when>
				<xsl:otherwise>
					<xsl:text disable-output-escaping="yes">&amp;#8594;</xsl:text>
				</xsl:otherwise>
			</xsl:choose>
		</html>
	</template>
	
	<template name="left-arrow" match="left-arrow|leftarrow|larr|larrow">
		<latex>
			<xsl:text> \ensuremath{\</xsl:text>
			<xsl:choose>
				<xsl:when test="@weight='double'">L</xsl:when>
				<xsl:otherwise>l</xsl:otherwise>
			</xsl:choose>
			<xsl:text>eftarrow} </xsl:text>
		</latex>
		<html>
			<xsl:choose>
				<xsl:when test="@weight='double'">
					<xsl:text disable-output-escaping="yes">&amp;#8656;</xsl:text>
				</xsl:when>
				<xsl:otherwise>
					<xsl:text disable-output-escaping="yes">&amp;#8592;</xsl:text>
				</xsl:otherwise>
			</xsl:choose>
		</html>
	</template>
	
	<!--
		The equivalent of LaTeX's "log-like functions".
		
		@name: The name of the function. We assume the names used by
		LaTeX here, as they work out correct anyway. There's actually
		nothing to stop you using any name you like, except that it'll
		probably die horribly in LaTeX :) [required]
	-->
	<template name="log-like-function" match="function">
		<latex>\ensuremath{\<xsl:value-of select="@name"/>}</latex>
		<html><xsl:value-of select="@name"/></html>
	</template>
	
	<!-- Any mathematical variable names. -->
	<template name="math-variable" match="variable|var">
		<latex>\ensuremath{\mathit{<xsl:apply-templates/>}}</latex>
		<html><I><xsl:apply-templates/></I></html>
	</template>
	
	<!-- A displayed fraction. Is there a nicer way of doing this in HTML? -->
	<template name="math-fraction" match="fraction">
		<latex>\ensuremath{\frac{<xsl:apply-templates select="numerator"/>}{<xsl:apply-templates select="denominator"/>}}</latex>
		<html>
			<SUP><xsl:apply-templates select="numerator"/></SUP>
			<xsl:text disable-output-escaping="yes">&amp;#8260;</xsl:text>
			<SUB><xsl:apply-templates select="denominator"/></SUB>
		</html>
	</template>
	
	
	<!--
		Format a University paper code. These normally appear in the form
		"SPOD 123", i.e., a space between the subject code and the paper
		number.
	-->
	<template name="paper" match="paper">
		<common>
			<xsl:apply-templates select="subject-code"/>
			<xsl:text> </xsl:text>
			<xsl:apply-templates select="paper-number"/>
		</common>
	</template>
	
	<template name="subject-code" match="paper/subject-code">
		<common><xsl:apply-templates/></common>
	</template>
		
	<template name="paper-number" match="paper/paper-number">
		<common><xsl:apply-templates/></common>
	</template>
	
	
	<!--
		Create a layout of multiple columns across the page. By default,
		columns are of equal width, but may be varied on a
		column-by-column basis. Each column is totally independent of
		the others, i.e., you can't have text automatically flowing from
		one column to the next (yet).
		
		@vspace: The amount of vertical space to put around the
		multi-column elements. [small, medium, big, LaTeX length, NONE]
		
		@align: Overall alignment of the columns (only relevant if the
		total width of the columns is less than the page width). [LEFT,
		center, right]
		
		@width: Total width of the column set, expressed as a fraction
		of the usable page width between 0 and 1 (this will be
		multiplied by 100 for HTML). Individual column widths are then
		expressed as a fraction of this total width. [default is 1]
	-->
	<template name="multi-column" match="multi-column">
		<latex>
			<xsl:variable name="total-width">
				<xsl:number value="1"/>
				<xsl:if test="@width"><xsl:value-of select="@width"/></xsl:if>
			</xsl:variable>
			<xsl:choose>
				<xsl:when test="@vspace = 'small'">\smallskip</xsl:when>
				<xsl:when test="@vspace = 'medium'">\medskip</xsl:when>
				<xsl:when test="@vspace = 'big'">\bigskip</xsl:when>
				<xsl:when test="@vspace">\vskip<xsl:value-of select="@vspace"/></xsl:when>
			</xsl:choose>
			\noindent
			<xsl:if test="@align">
				<xsl:text>\begin{</xsl:text>
				<xsl:choose>
					<xsl:when test="(@align = 'left') or (@align = 'right')">
						<xsl:text>flush</xsl:text><xsl:value-of select="@align"/>
					</xsl:when>
					<xsl:when test="@align = 'center'">
						<xsl:text>center</xsl:text>
					</xsl:when>
				</xsl:choose>
				<xsl:text>}</xsl:text>
			</xsl:if>
			<xsl:apply-templates>
				<xsl:with-param name="default-width">
					<xsl:number value="format-number($total-width div count(column),'0.00')"/>
				</xsl:with-param>
			</xsl:apply-templates>
			<xsl:if test="@align">
				<xsl:text>\end{</xsl:text>
				<xsl:choose>
					<xsl:when test="(@align = 'left') or (@align = 'right')">
						<xsl:text>flush</xsl:text><xsl:value-of select="@align"/>
					</xsl:when>
					<xsl:when test="@align = 'center'">
						<xsl:text>center</xsl:text>
					</xsl:when>
				</xsl:choose>
				<xsl:text>}</xsl:text>
			</xsl:if>
			<xsl:choose>
				<xsl:when test="@vspace = 'small'">\smallskip</xsl:when>
				<xsl:when test="@vspace = 'medium'">\medskip</xsl:when>
				<xsl:when test="@vspace = 'big'">\bigskip</xsl:when>
				<xsl:when test="@vspace">\vskip<xsl:value-of select="@vspace"/></xsl:when>
			</xsl:choose>
		</latex>
		<html>
			<xsl:variable name="total-width">
				<xsl:number value="100"/>
				<xsl:if test="@width"><xsl:value-of select="@width * 100"/></xsl:if>
			</xsl:variable>
			<xsl:if test="@vspace"><BR/></xsl:if>
			<TABLE BORDER="0" WIDTH="{$total-width}%">
				<xsl:if test="@align">
					<xsl:attribute name="ALIGN">
						<xsl:value-of select="@align"/>
					</xsl:attribute>
				</xsl:if>
				<TR>
					<xsl:apply-templates>
						<xsl:with-param name="default-width">
							<xsl:number value="round($total-width div count(column))"/>
						</xsl:with-param>
					</xsl:apply-templates>
				</TR>
			</TABLE>
			<xsl:if test="@vspace"><BR/></xsl:if>
		</html>
	</template>
	
	<!--
		A column within a multi-column element.
		
		$default-width: The default width of the column, expressed as a
		fraction of the total column set width. This is calculated by
		the <multi-column> template and should be 1/n of the column set
		width, where n is the number of columns.
		
		@width: The width of this particular column (overrides the
		default). This should be expressed as a fraction between 0 and 1
		(which is then multipled by 100 for HTML). Make sure that all
		widths add up!
		
		@align: How each individual column is to be aligned internally.
	-->
	<template name="multi-column-column" match="multi-column/column">
		<latex>
			<xsl:param name="default-width">1</xsl:param>
			<xsl:text>\begin{minipage}{</xsl:text>
			<xsl:choose>
				<xsl:when test="@width"><xsl:value-of select="@width"/></xsl:when>
				<xsl:otherwise><xsl:value-of select="$default-width"/></xsl:otherwise>
			</xsl:choose>
			<xsl:text>\columnwidth}</xsl:text>
			<xsl:if test="@align">
				<xsl:text>\begin{</xsl:text>
				<xsl:choose>
					<xsl:when test="(@align = 'left') or (@align = 'right')">
						<xsl:text>flush</xsl:text><xsl:value-of select="@align"/>
					</xsl:when>
					<xsl:when test="@align = 'center'">
						<xsl:text>center</xsl:text>
					</xsl:when>
				</xsl:choose>
				<xsl:text>}</xsl:text>
			</xsl:if>
			<xsl:apply-templates/>
			<xsl:if test="@align">
				<xsl:text>\end{</xsl:text>
				<xsl:choose>
					<xsl:when test="(@align = 'left') or (@align = 'right')">
						<xsl:text>flush</xsl:text><xsl:value-of select="@align"/>
					</xsl:when>
					<xsl:when test="@align = 'center'">
						<xsl:text>center</xsl:text>
					</xsl:when>
				</xsl:choose>
				<xsl:text>}</xsl:text>
			</xsl:if>
			<xsl:text>\end{minipage}</xsl:text>
		</latex>
		<html>
			<xsl:param name="default-width">100</xsl:param>
			<TD>
				<xsl:attribute name="WIDTH">
					<xsl:choose>
						<xsl:when test="@width"><xsl:value-of select="@width * 100"/></xsl:when>
						<xsl:otherwise><xsl:value-of select="$default-width"/></xsl:otherwise>
					</xsl:choose>
					<xsl:text>%</xsl:text>
				</xsl:attribute>
				<xsl:if test="@align">
					<xsl:attribute name="ALIGN">
						<xsl:value-of select="@align"/>
					</xsl:attribute>
				</xsl:if>
				<xsl:apply-templates/>
			</TD>
		</html>
	</template>
	
	
	<!--
		Center stuff on the page.
	-->
	<template name="center" match="center|centering">
		<latex>
			\begin{center}
				<xsl:apply-templates/>
			\end{center}
		</latex>
		<html>
			<CENTER>
				<xsl:apply-templates/>
			</CENTER>
		</html>
	</template>


</stylesheet>