<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:output method="text" encoding="ISO-8859-1" media-type="text/plain" /> <xsl:strip-space elements="*" /> <xsl:variable name="rows-per-week"> <xsl:value-of select="/calendar/@rows-per-week" /> <xsl:if test="not(/calendar/@rows-per-week)">2</xsl:if> </xsl:variable> <xsl:variable name="number-of-weeks"> <xsl:value-of select="/calendar/@number-of-weeks" /> <xsl:if test="not(/calendar/@number-of-weeks)">13</xsl:if> </xsl:variable> <!-- This is the number of columns in the output table. --> <xsl:variable name="number-of-columns">11</xsl:variable> <xsl:template match="/"> \newlength{\numberwidth} \settowidth{\numberwidth}{<xsl:number value="$number-of-weeks * 2" />} <xsl:apply-templates /> </xsl:template> <xsl:template match="calendar"> \begin{center} \begin{sideways} \resizebox{24cm}{!}{% \begin{tabular}{|c|c|c|c|l|c|c|c|c|c|c|} <!-- Calendar heading. --> \multicolumn{<xsl:value-of select="$number-of-columns" />}{c}{\LARGE\textbf{<xsl:apply-templates select="paper" /> Paper Calendar, <xsl:apply-templates select="period" /><xsl:text> </xsl:text><xsl:apply-templates select="year" />}} \\ \multicolumn{<xsl:value-of select="$number-of-columns" />}{c}{} \\ \hline <!-- The calendar itself. --> <xsl:apply-templates select="header" /> \hline\hline <xsl:apply-templates select="body" /> \hline\hline <xsl:apply-templates select="footer" /> \end{tabular}% } \end{sideways} \end{center} </xsl:template> <!-- Header/footer rows for the calendar table. To get proper table headings/footings, use HEADING/FOOTING. For other text, use NOTE. --> <xsl:template match="header|footer"> <xsl:apply-templates /> \\ \hline </xsl:template> <!-- A table heading or footing, bolded, centered, etc. --> <xsl:template match="heading|footing"> <xsl:if test="@columns"> \multicolumn{<xsl:value-of select="@columns" />}{|c|}{% </xsl:if> \textbf{<xsl:apply-templates />}% <xsl:if test="@columns"> } </xsl:if> <xsl:if test="position() != last()"> & </xsl:if> </xsl:template> <!-- A miscellaneous piece of text to be inserted somewhere in the calendar table. --> <xsl:template match="note"> <xsl:if test="@columns"> \multicolumn{<xsl:value-of select="@columns" />}{|l|}{% </xsl:if> <xsl:apply-templates />% <xsl:if test="@columns"> } </xsl:if> </xsl:template> <!-- A week in the calendar. Each week has an associated number (automatically generated) and a date range, and spans some defined number of rows (default 2). The week number and date range are only generated for the first of these rows. --> <xsl:template match="week"> <xsl:for-each select="row"> <!-- If we're going to start a new section, draw a rule under the previous section to separate them. --> <xsl:if test="count(section) != 0"> \cline{3-3} </xsl:if> <!-- Output the week number and dates columns. --> <xsl:choose> <xsl:when test="position() = 1"> <!-- Week number, first row only. --> \multirow{<xsl:value-of select="$rows-per-week" />}{*}{% \makebox[\numberwidth][c]{% <xsl:number value="1 + count(preceding::week[not(@holiday)])" />% }% }& <!-- Date range, first row only. --> \multirow{<xsl:value-of select="$rows-per-week" />}{*}{% \begin{tabular}{c}% <xsl:apply-templates select="../dates" />% \end{tabular}% }& </xsl:when> <xsl:otherwise> && </xsl:otherwise> </xsl:choose> <!-- We have to apply each of the sub-templates manually, not so much to ensure the correct ordering, but so that we can output empty cells when an element is missing. --> <xsl:apply-templates select="section" /> & <xsl:apply-templates select="lecture" /> <xsl:if test="count(lecture) = 0"> \multicolumn{2}{|c|}{} </xsl:if> & <xsl:apply-templates select="reading" /> & <!-- Labs and tutorials are tricky because we can't just output two empty cells and continue. If the previous LABORATORY or TUTORIAL entry is empty, then outputting two empty cells would look wrong (because these usually span at least two rows). The converse is also true. --> <xsl:apply-templates select="laboratory" /> <xsl:if test="count(laboratory) = 0"> <xsl:choose> <xsl:when test="not(preceding::row[1]/laboratory/node())"> \multicolumn{2}{|c|}{} </xsl:when> <xsl:otherwise> & </xsl:otherwise> </xsl:choose> </xsl:if> & <xsl:apply-templates select="tutorial" /> <xsl:if test="count(tutorial) = 0"> <xsl:choose> <xsl:when test="not(preceding::row[1]/tutorial/node())"> \multicolumn{2}{|c|}{} </xsl:when> <xsl:otherwise> & </xsl:otherwise> </xsl:choose> </xsl:if> & <xsl:apply-templates select="assessment" /> <!-- Note assumption that a lecture is always a single row. --> \\ \cline{4-5} <xsl:if test="position() = $rows-per-week"> \cline{1-2}\cline{6-6}\cline{11-11} <xsl:if test="not(preceding::row[1]/laboratory/@rows)"> \cline{7-8} </xsl:if> <xsl:if test="not(preceding::row[1]/tutorial/@rows)"> \cline{9-10} </xsl:if> </xsl:if> </xsl:for-each> </xsl:template> <!-- Weeks that are holidays have no week number or date range, just a text description. --> <xsl:template match="week[@holiday]"> \hline\hline \multicolumn{<xsl:value-of select="$number-of-columns" />}{|c|}{% \multirow{2}{*}{\LARGE\textsf{\textbf{<xsl:apply-templates />}}}% } \\ \multicolumn{11}{|c|}{} \\ \hline\hline </xsl:template> <!-- Output a calendar entry for a lecture. Note that lectures are always assumed to span a single row. Lectures are automatically numbered. --> <xsl:template match="lecture[node() and not(@holiday)]"> <xsl:number value="1 + count(preceding::lecture[node() and not(@holiday)])" /> & <xsl:apply-templates /> </xsl:template> <!-- Output a calendar entry for a lecture that occurs on a holiday. These aren't numbered. --> <xsl:template match="lecture[@holiday]"> \multicolumn{2}{|c|}{\textsf{\textbf{<xsl:apply-templates />}}} </xsl:template> <!-- Output an empty lecture cell. --> <xsl:template match="lecture[not(node())]"> \multicolumn{2}{|c|}{}} </xsl:template> <!-- Output a calendar entry for a laboratory. Laboratories are automatically numbered. --> <xsl:template match="laboratory[node()]"> <xsl:variable name="num-rows"> <xsl:value-of select="@rows" /> <xsl:if test="not(@rows)"> <xsl:value-of select="$rows-per-week" /> </xsl:if> </xsl:variable> \multirow{<xsl:value-of select="$num-rows" />}{*}{% \makebox[\numberwidth][c]{% <xsl:number value="1 + count(preceding::laboratory[node()])" />% }% }& \multirow{<xsl:value-of select="$num-rows" />}{*}{% \begin{tabular}{c}% <xsl:apply-templates />% \end{tabular}% } </xsl:template> <!-- Output a calendar entry for a tutorial. Tutorials are automatically numbered. --> <xsl:template match="tutorial[node()]"> <xsl:variable name="num-rows"> <xsl:value-of select="@rows" /> <xsl:if test="not(@rows)"> <xsl:value-of select="$rows-per-week" /> </xsl:if> </xsl:variable> \multirow{<xsl:value-of select="$num-rows" />}{*}{% \makebox[\numberwidth][c]{% <xsl:number value="1 + count(preceding::tutorial[node()])" />% }% }& \multirow{<xsl:value-of select="$num-rows" />}{*}{% \begin{tabular}{c}% <xsl:apply-templates />% \end{tabular}% } </xsl:template> <!-- Output an empty laboratory/tutorial cell. --> <xsl:template match="laboratory[not(node())]|tutorial[not(node())]"> <xsl:variable name="num-rows"> <xsl:value-of select="@rows" /> <xsl:if test="not(@rows)"> <xsl:value-of select="$rows-per-week" /> </xsl:if> </xsl:variable> \multicolumn{2}{|c|}{\multirow{<xsl:value-of select="$num-rows" />}{*}{}} </xsl:template> <!-- Output a calendar entry for a section, reading or asssement (all use the same formatting). --> <xsl:template match="section[node()]|reading[node()]|assessment[node()]"> <xsl:variable name="num-rows"> <xsl:value-of select="@rows" /> <xsl:if test="not(@rows)"> <xsl:value-of select="$rows-per-week" /> </xsl:if> </xsl:variable> \multirow{<xsl:value-of select="$num-rows" />}{*}{% \begin{tabular}{c}% <xsl:apply-templates />% \end{tabular}% } </xsl:template> <!-- Output an empty section, reading or assessment cell. --> <xsl:template match="section[not(node())]|reading[not(node())]|assessment[not(node())]"> <xsl:variable name="num-rows"> <xsl:value-of select="@rows" /> <xsl:if test="not(@rows)"> <xsl:value-of select="$rows-per-week" /> </xsl:if> </xsl:variable> \multirow{<xsl:value-of select="$num-rows" />}{*}{} </xsl:template> <!-- Generate a link. --> <!-- <xsl:template match="link"> --> <!-- <a> --> <!-- <xsl:attribute name="href"> --> <!-- <xsl:value-of select="@href" /> --> <!-- </xsl:attribute> --> <!-- <xsl:apply-templates /> --> <!-- </a> --> <!-- </xsl:template> --> <!-- Wrap quotes around a string. If the attribute SINGLE is set to "yes", use single quotes instead of double. --> <xsl:template match="quote"> <xsl:choose> <xsl:when test="@single = 'yes'"> <xsl:text>`</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>``</xsl:text> </xsl:otherwise> </xsl:choose> <xsl:apply-templates /> <xsl:choose> <xsl:when test="@single = 'yes'"> <xsl:text>'</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>''</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- Output an ampersand character. --> <xsl:template match="ampersand"> <xsl:text>\&</xsl:text> </xsl:template> <!-- Output an en-dash entity character. --> <xsl:template match="endash"> <xsl:text>--</xsl:text> </xsl:template> <!-- Output a section symbol character. --> <xsl:template match="sect"> <xsl:text>\S{}</xsl:text> </xsl:template> <!-- Output a hash character. --> <xsl:template match="hash"> <xsl:text>\#</xsl:text> </xsl:template> <!-- Output an apostrophe. --> <xsl:template match="apostrophe"> <xsl:text>'</xsl:text> </xsl:template> <!-- Miscellaneous elements to be mapped straight through. --> <xsl:template match="strong|b"> <xsl:text>\textbf{</xsl:text> <xsl:apply-templates /> <xsl:text>}</xsl:text> </xsl:template> <xsl:template match="em|i"> <xsl:text>\emph{</xsl:text> <xsl:apply-templates /> <xsl:text>}</xsl:text> </xsl:template> <xsl:template match="u"> <xsl:text>\underline{</xsl:text> <xsl:apply-templates /> <xsl:text>}</xsl:text> </xsl:template> <xsl:template match="br"> <xsl:text>\\</xsl:text> </xsl:template> <xsl:template match="code"> <xsl:text>\texttt{</xsl:text> <xsl:apply-templates /> <xsl:text>}</xsl:text> </xsl:template> </xsl:stylesheet>