Newer
Older
XML / modules / multi-column.xml
<?xml version="1.0" encoding="utf-8"?>

<!--
	Create a layout of multiple columns across the page.
-->

<stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


	<!--
		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). In LaTeX, the multi-column layout is formatted as a separate paragraph to prevent run-on text into the right margin.
		
		@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]
		
		TODO: The default column width goes awry when the total width is less than 1.0. It works OK if you explicitly specify individual column widths.
	-->
	<template name="multi-column" match="multi-column">
		<common formats="/latex/xelatex/">
			<xsl:variable name="total-width">
				<xsl:value-of select="1" />
				<xsl:if test="@width"><xsl:value-of select="@width" /></xsl:if>
			</xsl:variable>
			
			<!--
				Ensure that layout is treated as a separate paragraph.
			-->
			<xsl:call-template name="newline-internal" />
			<xsl:call-template name="newline-internal" />
			
			<xsl:choose>
				<xsl:when test="@vspace eq 'small'"><xsl:text>\smallskip</xsl:text></xsl:when>
				<xsl:when test="@vspace eq 'medium'"><xsl:text>\medskip</xsl:text></xsl:when>
				<xsl:when test="@vspace eq 'big'"><xsl:text>\bigskip</xsl:text></xsl:when>
				<xsl:when test="@vspace"><xsl:text>\vskip</xsl:text><xsl:value-of select="@vspace" /></xsl:when>
			</xsl:choose>
			<xsl:text>\noindent</xsl:text>
			<xsl:if test="@align">
				<xsl:text>\begin{</xsl:text>
				<xsl:choose>
					<xsl:when test="@align = ('left', 'right')">
						<xsl:text>flush</xsl:text><xsl:value-of select="@align" />
					</xsl:when>
					<xsl:when test="@align = ('center', 'centre')">
						<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:value-of select="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', 'right')">
						<xsl:text>flush</xsl:text><xsl:value-of select="@align" />
					</xsl:when>
					<xsl:when test="@align = ('center', 'centre')">
						<xsl:text>center</xsl:text>
					</xsl:when>
				</xsl:choose>
				<xsl:text>}</xsl:text>
			</xsl:if>
			<xsl:choose>
				<xsl:when test="@vspace eq 'small'"><xsl:text>\smallskip</xsl:text></xsl:when>
				<xsl:when test="@vspace eq 'medium'"><xsl:text>\medskip</xsl:text></xsl:when>
				<xsl:when test="@vspace eq 'big'"><xsl:text>\bigskip</xsl:text></xsl:when>
				<xsl:when test="@vspace"><xsl:text>\vskip</xsl:text><xsl:value-of select="@vspace" /></xsl:when>
			</xsl:choose>
			
			<!--
				Ensure that layout is treated as a separate paragraph.
			-->
			<xsl:call-template name="newline-internal" />
			<xsl:call-template name="newline-internal" />
		</common>
		<common formats="/html/xhtml/">
			<xsl:variable name="total-width">
				<xsl:value-of select="100" />
				<xsl:if test="@width"><xsl:value-of select="@width * 100" /></xsl:if>
			</xsl:variable>
			<xsl:if test="@vspace"><br /></xsl:if>
			
			<!-- TODO: change this to use CSS instead of HTML tables. -->
			<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:value-of select="round($total-width div count(column))" />
						</xsl:with-param>
					</xsl:apply-templates>
				</tr>
			</table>
			<xsl:if test="@vspace"><br /></xsl:if>
		</common>
	</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">
		<common formats="/latex/xelatex/">
			<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', 'right')">
						<xsl:text>flush</xsl:text><xsl:value-of select="@align" />
					</xsl:when>
					<xsl:when test="@align = ('center', 'centre')">
						<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', 'right')">
						<xsl:text>flush</xsl:text><xsl:value-of select="@align" />
					</xsl:when>
					<xsl:when test="@align = ('center', 'centre')">
						<xsl:text>center</xsl:text>
					</xsl:when>
				</xsl:choose>
				<xsl:text>}</xsl:text>
			</xsl:if>
			<xsl:text>\end{minipage}</xsl:text>
		</common>
		<common formats="/html/xhtml/">
			<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>
		</common>
	</template>


</stylesheet>