• Added latex-calendar-break template to support breaking a calendar across pages in (Xe)LaTeX.
• Refactored calendar tabular preamble and postamble into separate templates.
• Made use of tunnelled parameters to reduce the amount of explicit parameter passing.
1 parent 8ddba48 commit 7e7c6af5695b4bba4111aca2c80ebfab01d8f5a3
Nigel Stanger authored on 3 Jul 2014
Showing 1 changed file
View
616
modules/paper-calendar.xml
This is mainly relevant to (Xe)LaTeX in order to underline cells correctly. In (Xe)LaTeX it doesn't matter if we draw the same \clines multiple times, so if a column doesn't exist, we just set it's column number to the column number of the previous column. HTML doesn't really care, but we need to do the calculation anyway in order to work out the correct number of columns.
Note that we need to cover both the case of a calendar for a single period, which will have the body element as an immediate child of calendar, versus a calendar for multiple periods, which will have the body elements as immmediate children of calendar/period.
Note also the implied assumption that a calendar with multiple periods will have the same column structure for all periods. This may or may not be a valid assumption in future!
-->
<xsl:variable name="week-column">1</xsl:variable>
<xsl:variable name="date-column">2</xsl:variable>
<xsl:variable name="section-column" select="
<xsl:text>}</xsl:text>
<xsl:call-template name="newline-internal" />
<!--
The processing of the actual calendar content is split off into a separate callable template (latex-calendar-content) so that we can handle single-period and multiple-period calendars with the same code.
The processing of the actual calendar content is split off into a separate callable template (generate-calendar-content) so that we can handle single-period and multiple-period calendars with the same code. We use tunnelled parameters to avoid having to explicitly pass the damn things all over the place! (Except for the first time, of course.)
-->
<xsl:choose>
<!--
If the calendar has multiple periods, then each period will be enclosed inside its own period element. We call the template once for each of these, generating a new tabular each time (i.e., each period effectively gets output as a calendar in its own right). The teaching period for each part is expanded from its @code attribute.
-->
<xsl:when test="period">
<xsl:for-each select="period">
<xsl:call-template name="generate-calendar-content">
<xsl:with-param name="week-column" select="xs:integer( $week-column )" />
<xsl:with-param name="date-column" select="xs:integer( $date-column )" />
<xsl:with-param name="section-column" select="xs:integer( $section-column )" />
<xsl:with-param name="lecture-column-1" select="xs:integer( $lecture-column-1 )" />
<xsl:with-param name="lecture-column-2" select="xs:integer( $lecture-column-2 )" />
<xsl:with-param name="reading-column" select="xs:integer( $reading-column )" />
<xsl:with-param name="laboratory-column-1" select="xs:integer( $laboratory-column-1 )" />
<xsl:with-param name="laboratory-column-2" select="xs:integer( $laboratory-column-2 )" />
<xsl:with-param name="tutorial-column-1" select="xs:integer( $tutorial-column-1 )" />
<xsl:with-param name="tutorial-column-2" select="xs:integer( $tutorial-column-2 )" />
<xsl:with-param name="assessment-column" select="xs:integer( $assessment-column )" />
<xsl:with-param name="num-columns" select="xs:integer( $num-columns )" />
<xsl:with-param name="teaching-period" select="infosci:expand-period-code( @code )" />
<xsl:with-param name="week-column" select="xs:integer( $week-column )" tunnel="yes" />
<xsl:with-param name="date-column" select="xs:integer( $date-column )" tunnel="yes" />
<xsl:with-param name="section-column" select="xs:integer( $section-column )" tunnel="yes" />
<xsl:with-param name="lecture-column-1" select="xs:integer( $lecture-column-1 )" tunnel="yes" />
<xsl:with-param name="lecture-column-2" select="xs:integer( $lecture-column-2 )" tunnel="yes" />
<xsl:with-param name="reading-column" select="xs:integer( $reading-column )" tunnel="yes" />
<xsl:with-param name="laboratory-column-1" select="xs:integer( $laboratory-column-1 )" tunnel="yes" />
<xsl:with-param name="laboratory-column-2" select="xs:integer( $laboratory-column-2 )" tunnel="yes" />
<xsl:with-param name="tutorial-column-1" select="xs:integer( $tutorial-column-1 )" tunnel="yes" />
<xsl:with-param name="tutorial-column-2" select="xs:integer( $tutorial-column-2 )" tunnel="yes" />
<xsl:with-param name="assessment-column" select="xs:integer( $assessment-column )" tunnel="yes" />
<xsl:with-param name="num-columns" select="xs:integer( $num-columns )" tunnel="yes" />
<xsl:with-param name="teaching-period" select="infosci:expand-period-code( @code )" tunnel="yes" />
</xsl:call-template>
</xsl:for-each>
</xsl:when>
<!--
If the calendar has only one period, there will be no period elements, and we thus need to call the template just once. The teaching period for the calendar is specified by the global stylesheet variable $period-string.
If the calendar has only one period, there will be no period elements, and we thus need to call the template just once. The teaching period for the calendar is specified by the global stylesheet variable $period-string (which is already expanded).
-->
<xsl:otherwise>
<xsl:call-template name="generate-calendar-content">
<xsl:with-param name="week-column" select="xs:integer( $week-column )" />
<xsl:with-param name="date-column" select="xs:integer( $date-column )" />
<xsl:with-param name="section-column" select="xs:integer( $section-column )" />
<xsl:with-param name="lecture-column-1" select="xs:integer( $lecture-column-1 )" />
<xsl:with-param name="lecture-column-2" select="xs:integer( $lecture-column-2 )" />
<xsl:with-param name="reading-column" select="xs:integer( $reading-column )" />
<xsl:with-param name="laboratory-column-1" select="xs:integer( $laboratory-column-1 )" />
<xsl:with-param name="laboratory-column-2" select="xs:integer( $laboratory-column-2 )" />
<xsl:with-param name="tutorial-column-1" select="xs:integer( $tutorial-column-1 )" />
<xsl:with-param name="tutorial-column-2" select="xs:integer( $tutorial-column-2 )" />
<xsl:with-param name="assessment-column" select="xs:integer( $assessment-column )" />
<xsl:with-param name="num-columns" select="xs:integer( $num-columns )" />
<xsl:with-param name="teaching-period" select="$period-string" />
<xsl:with-param name="week-column" select="xs:integer( $week-column )" tunnel="yes" />
<xsl:with-param name="date-column" select="xs:integer( $date-column )" tunnel="yes" />
<xsl:with-param name="section-column" select="xs:integer( $section-column )" tunnel="yes" />
<xsl:with-param name="lecture-column-1" select="xs:integer( $lecture-column-1 )" tunnel="yes" />
<xsl:with-param name="lecture-column-2" select="xs:integer( $lecture-column-2 )" tunnel="yes" />
<xsl:with-param name="reading-column" select="xs:integer( $reading-column )" tunnel="yes" />
<xsl:with-param name="laboratory-column-1" select="xs:integer( $laboratory-column-1 )" tunnel="yes" />
<xsl:with-param name="laboratory-column-2" select="xs:integer( $laboratory-column-2 )" tunnel="yes" />
<xsl:with-param name="tutorial-column-1" select="xs:integer( $tutorial-column-1 )" tunnel="yes" />
<xsl:with-param name="tutorial-column-2" select="xs:integer( $tutorial-column-2 )" tunnel="yes" />
<xsl:with-param name="assessment-column" select="xs:integer( $assessment-column )" tunnel="yes" />
<xsl:with-param name="num-columns" select="xs:integer( $num-columns )" tunnel="yes" />
<xsl:with-param name="teaching-period" select="$period-string" tunnel="yes" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</common>
<common formats="/html/xhtml/">
<!--
This is identical to the calendar/period handling in the LaTeX formats above. I'd prefer to define this code only once, but can't because of the way the common element works when no formats are specified, i.e., ALL non-format-specifi common code appears at the start of the template.
This is identical to the calendar/period handling in the LaTeX formats above. I'd prefer to define this code only once, but can't because of the way the common element works when no formats are specified, i.e., ALL non-format-specific common code appears at the start of the template.
Incidentally, it sounds nice for multiple-period calendars to generate a single HTML table covering all periods rather than splitting it into separate tables. However, this becomes a bit fraught when you start to consider what to do with (possibly different) headers and footers for each period, and how to handle the break between periods. You could probably do something with lots of conditional processing, but it would be pretty hacky. It's much easier to just output a separate self-contained table for each period.
-->
<xsl:choose>
<xsl:when test="period">
<xsl:for-each select="period">
<xsl:call-template name="generate-calendar-content">
<xsl:with-param name="week-column" select="xs:integer( $week-column )" />
<xsl:with-param name="date-column" select="xs:integer( $date-column )" />
<xsl:with-param name="section-column" select="xs:integer( $section-column )" />
<xsl:with-param name="lecture-column-1" select="xs:integer( $lecture-column-1 )" />
<xsl:with-param name="lecture-column-2" select="xs:integer( $lecture-column-2 )" />
<xsl:with-param name="reading-column" select="xs:integer( $reading-column )" />
<xsl:with-param name="laboratory-column-1" select="xs:integer( $laboratory-column-1 )" />
<xsl:with-param name="laboratory-column-2" select="xs:integer( $laboratory-column-2 )" />
<xsl:with-param name="tutorial-column-1" select="xs:integer( $tutorial-column-1 )" />
<xsl:with-param name="tutorial-column-2" select="xs:integer( $tutorial-column-2 )" />
<xsl:with-param name="assessment-column" select="xs:integer( $assessment-column )" />
<xsl:with-param name="num-columns" select="xs:integer( $num-columns )" />
<xsl:with-param name="teaching-period" select="infosci:expand-period-code( @code )" />
<xsl:with-param name="week-column" select="xs:integer( $week-column )" tunnel="yes" />
<xsl:with-param name="date-column" select="xs:integer( $date-column )" tunnel="yes" />
<xsl:with-param name="section-column" select="xs:integer( $section-column )" tunnel="yes" />
<xsl:with-param name="lecture-column-1" select="xs:integer( $lecture-column-1 )" tunnel="yes" />
<xsl:with-param name="lecture-column-2" select="xs:integer( $lecture-column-2 )" tunnel="yes" />
<xsl:with-param name="reading-column" select="xs:integer( $reading-column )" tunnel="yes" />
<xsl:with-param name="laboratory-column-1" select="xs:integer( $laboratory-column-1 )" tunnel="yes" />
<xsl:with-param name="laboratory-column-2" select="xs:integer( $laboratory-column-2 )" tunnel="yes" />
<xsl:with-param name="tutorial-column-1" select="xs:integer( $tutorial-column-1 )" tunnel="yes" />
<xsl:with-param name="tutorial-column-2" select="xs:integer( $tutorial-column-2 )" tunnel="yes" />
<xsl:with-param name="assessment-column" select="xs:integer( $assessment-column )" tunnel="yes" />
<xsl:with-param name="num-columns" select="xs:integer( $num-columns )" tunnel="yes" />
<xsl:with-param name="teaching-period" select="infosci:expand-period-code( @code )" tunnel="yes" />
</xsl:call-template>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="generate-calendar-content">
<xsl:with-param name="week-column" select="xs:integer( $week-column )" />
<xsl:with-param name="date-column" select="xs:integer( $date-column )" />
<xsl:with-param name="section-column" select="xs:integer( $section-column )" />
<xsl:with-param name="lecture-column-1" select="xs:integer( $lecture-column-1 )" />
<xsl:with-param name="lecture-column-2" select="xs:integer( $lecture-column-2 )" />
<xsl:with-param name="reading-column" select="xs:integer( $reading-column )" />
<xsl:with-param name="laboratory-column-1" select="xs:integer( $laboratory-column-1 )" />
<xsl:with-param name="laboratory-column-2" select="xs:integer( $laboratory-column-2 )" />
<xsl:with-param name="tutorial-column-1" select="xs:integer( $tutorial-column-1 )" />
<xsl:with-param name="tutorial-column-2" select="xs:integer( $tutorial-column-2 )" />
<xsl:with-param name="assessment-column" select="xs:integer( $assessment-column )" />
<xsl:with-param name="num-columns" select="xs:integer( $num-columns )" />
<xsl:with-param name="teaching-period" select="$period-string" />
<xsl:with-param name="week-column" select="xs:integer( $week-column )" tunnel="yes" />
<xsl:with-param name="date-column" select="xs:integer( $date-column )" tunnel="yes" />
<xsl:with-param name="section-column" select="xs:integer( $section-column )" tunnel="yes" />
<xsl:with-param name="lecture-column-1" select="xs:integer( $lecture-column-1 )" tunnel="yes" />
<xsl:with-param name="lecture-column-2" select="xs:integer( $lecture-column-2 )" tunnel="yes" />
<xsl:with-param name="reading-column" select="xs:integer( $reading-column )" tunnel="yes" />
<xsl:with-param name="laboratory-column-1" select="xs:integer( $laboratory-column-1 )" tunnel="yes" />
<xsl:with-param name="laboratory-column-2" select="xs:integer( $laboratory-column-2 )" tunnel="yes" />
<xsl:with-param name="tutorial-column-1" select="xs:integer( $tutorial-column-1 )" tunnel="yes" />
<xsl:with-param name="tutorial-column-2" select="xs:integer( $tutorial-column-2 )" tunnel="yes" />
<xsl:with-param name="assessment-column" select="xs:integer( $assessment-column )" tunnel="yes" />
<xsl:with-param name="num-columns" select="xs:integer( $num-columns )" tunnel="yes" />
<xsl:with-param name="teaching-period" select="$period-string" tunnel="yes" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</common>
Every variable defined in the calendar template above is passed as a parameter, so there's little point in listing them here. The only extra one is $teaching-period.
-->
<template name="generate-calendar-content">
<common>
<xsl:param name="week-column" />
<xsl:param name="date-column" />
<xsl:param name="section-column" />
<xsl:param name="lecture-column-1" />
<xsl:param name="lecture-column-2" />
<xsl:param name="reading-column" />
<xsl:param name="laboratory-column-1" />
<xsl:param name="laboratory-column-2" />
<xsl:param name="tutorial-column-1" />
<xsl:param name="tutorial-column-2" />
<xsl:param name="assessment-column" />
<xsl:param name="num-columns" />
<xsl:param name="teaching-period" />
</common>
<common formats="/latex/xelatex/">
<xsl:text>\begin{center}</xsl:text>
<xsl:call-template name="newline-internal" />
<!-- TODO: Probably not if standalone! -->
<xsl:text>\begin{sideways}</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:text>\resizebox{24cm}{!}{%</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:text>\begin{tabular}{|c|c</xsl:text>
<xsl:if test="$section-column > $date-column">
<xsl:text>|c</xsl:text>
</xsl:if>
<xsl:if test="$lecture-column-1 > $section-column">
<xsl:text>|c|l</xsl:text>
</xsl:if>
<xsl:if test="$reading-column > $lecture-column-2">
<xsl:text>|c</xsl:text>
</xsl:if>
<xsl:if test="$laboratory-column-1 > $reading-column">
<xsl:text>|c|c</xsl:text>
</xsl:if>
<xsl:if test="$tutorial-column-1 > $laboratory-column-2">
<xsl:text>|c|c</xsl:text>
</xsl:if>
<xsl:if test="$assessment-column > $tutorial-column-2">
<xsl:text>|c</xsl:text>
</xsl:if>
<xsl:text>|}</xsl:text>
<xsl:call-template name="newline-internal" />
<!--
Calendar heading. We can't use generate-content-cell for this, because we're doing more complex processing of the cell contents than is possible with generate-content-cell. Here, we're calling three separate templates interspersed with text, whereas generate-content-cell can only accept a simple list of nodes to apply-templates to.
-->
<xsl:text>\multicolumn{</xsl:text>
<xsl:value-of select="$num-columns" />
<xsl:text>}{c}{\LARGE\textbf{</xsl:text>
<xsl:call-template name="PaperCode" />
<xsl:text> Teaching Calendar, </xsl:text>
<xsl:value-of select="$teaching-period" />
<xsl:text>, </xsl:text>
<xsl:call-template name="PaperYear" />
<xsl:text>}} \\</xsl:text>
<xsl:call-template name="newline-internal" />
<!--
Note that using generate-empty-cell here requires about three time as much code as just doing it inline :), but we gain in terms of output consistency.
-->
<xsl:call-template name="generate-empty-cell">
<xsl:with-param name="columns" select="xs:integer( $num-columns )" />
<xsl:with-param name="rows">1</xsl:with-param>
<xsl:with-param name="column-format">c</xsl:with-param>
</xsl:call-template>
<xsl:text> \\</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:text>\hline</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:param name="week-column" tunnel="yes" />
<xsl:param name="date-column" tunnel="yes" />
<xsl:param name="section-column" tunnel="yes" />
<xsl:param name="lecture-column-1" tunnel="yes" />
<xsl:param name="lecture-column-2" tunnel="yes" />
<xsl:param name="reading-column" tunnel="yes" />
<xsl:param name="laboratory-column-1" tunnel="yes" />
<xsl:param name="laboratory-column-2" tunnel="yes" />
<xsl:param name="tutorial-column-1" tunnel="yes" />
<xsl:param name="tutorial-column-2" tunnel="yes" />
<xsl:param name="assessment-column" tunnel="yes" />
<xsl:param name="num-columns" tunnel="yes" />
<xsl:param name="teaching-period" tunnel="yes" />
</common>
<common formats="/latex/xelatex/">
<!-- Calendar heading boilerplate, i.e., all the \begin{environment}, etc. -->
<xsl:call-template name="generate-latex-calendar-preamble" />
<!-- The calendar itself. -->
<xsl:apply-templates select="header">
<xsl:with-param name="num-columns" select="xs:integer( $num-columns )" />
</xsl:apply-templates>
<xsl:apply-templates select="header" />
<xsl:call-template name="newline-internal" />
<xsl:text>\hline\hline</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:apply-templates select="body">
<xsl:with-param name="week-column" select="xs:integer( $week-column )" />
<xsl:with-param name="date-column" select="xs:integer( $date-column )" />
<xsl:with-param name="section-column" select="xs:integer( $section-column )" />
<xsl:with-param name="lecture-column-1" select="xs:integer( $lecture-column-1 )" />
<xsl:with-param name="lecture-column-2" select="xs:integer( $lecture-column-2 )" />
<xsl:with-param name="reading-column" select="xs:integer( $reading-column )" />
<xsl:with-param name="laboratory-column-1" select="xs:integer( $laboratory-column-1 )" />
<xsl:with-param name="laboratory-column-2" select="xs:integer( $laboratory-column-2 )" />
<xsl:with-param name="tutorial-column-1" select="xs:integer( $tutorial-column-1 )" />
<xsl:with-param name="tutorial-column-2" select="xs:integer( $tutorial-column-2 )" />
<xsl:with-param name="assessment-column" select="xs:integer( $assessment-column )" />
<xsl:with-param name="num-columns" select="xs:integer( $num-columns )" />
</xsl:apply-templates>
<xsl:call-template name="newline-internal" />
<xsl:apply-templates select="body" />
<xsl:call-template name="newline-internal" />
<xsl:text>\hline\hline</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:apply-templates select="footer">
<xsl:with-param name="num-columns" select="xs:integer( $num-columns )" />
</xsl:apply-templates>
<xsl:call-template name="newline-internal" />
<xsl:text>\hline</xsl:text>
<xsl:call-template name="newline-internal" />
 
<xsl:text>\end{tabular}%</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:text>}</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:text>\end{sideways}</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:text>\end{center}</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:apply-templates select="footer" />
<xsl:call-template name="newline-internal" />
<!-- Calendar footing boilerplate, i.e., all the \end{environment}, etc. -->
<xsl:call-template name="generate-latex-calendar-postamble" />
</common>
<common formats="/html/xhtml/">
<!-- Calendar heading. -->
<h2>
</h2>
<!-- The calendar itself. -->
<div class="sans">
<table class="small calendar" summary="Paper calendar with relevant links" cellspacing="0">
<table class="small calendar" summary="Teaching calendar with relevant links" cellspacing="0">
<!--
I was going to generate COL elements here, but they don't seem to be supported by all browsers. Damn. The same applies for THEAD/TFOOT/TBODY, but I may as well leave them in for the browsers that do support them.
-->
<thead class="calendar">
<xsl:apply-templates select="header">
<xsl:with-param name="num-columns" select="xs:integer( $num-columns )" />
</xsl:apply-templates>
<xsl:apply-templates select="header" />
</thead>
<tfoot class="calendar">
<xsl:apply-templates select="footer">
<xsl:with-param name="num-columns" select="xs:integer( $num-columns )" />
</xsl:apply-templates>
<xsl:apply-templates select="footer" />
</tfoot>
<tbody class="calendar">
<xsl:apply-templates select="body">
<xsl:with-param name="week-column" select="xs:integer( $week-column )" />
<xsl:with-param name="date-column" select="xs:integer( $date-column )" />
<xsl:with-param name="section-column" select="xs:integer( $section-column )" />
<xsl:with-param name="lecture-column-1" select="xs:integer( $lecture-column-1 )" />
<xsl:with-param name="lecture-column-2" select="xs:integer( $lecture-column-2 )" />
<xsl:with-param name="reading-column" select="xs:integer( $reading-column )" />
<xsl:with-param name="laboratory-column-1" select="xs:integer( $laboratory-column-1 )" />
<xsl:with-param name="laboratory-column-2" select="xs:integer( $laboratory-column-2 )" />
<xsl:with-param name="tutorial-column-1" select="xs:integer( $tutorial-column-1 )" />
<xsl:with-param name="tutorial-column-2" select="xs:integer( $tutorial-column-2 )" />
<xsl:with-param name="assessment-column" select="xs:integer( $assessment-column )" />
<xsl:with-param name="num-columns" select="xs:integer( $num-columns )" />
</xsl:apply-templates>
<xsl:apply-templates select="body" />
</tbody>
</table>
</div>
</common>
<!--
Header/footer rows for the calendar table. To get proper table headings/footings, use HEADING/FOOTING. For other text, use NOTE.
-->
<template match="header|footer">
<common>
<xsl:param name="num-columns" />
</common>
<common formats="/latex/xelatex/">
<xsl:apply-templates>
<xsl:with-param name="num-columns" select="xs:integer( $num-columns )" />
</xsl:apply-templates>
<common formats="/latex/xelatex/">
<xsl:apply-templates />
<xsl:text> \\</xsl:text>
<!--
It's left to the parent template to add horizontal rules after the last header/footer element, as what gets output may vary depending on position in the table (e.g., double rule after the last header, but single rule after the last footer).
<xsl:call-template name="newline-internal" />
</common>
<common formats="/html/xhtml/">
<tr>
<xsl:apply-templates>
<xsl:with-param name="num-columns" select="xs:integer( $num-columns )" />
</xsl:apply-templates>
<xsl:apply-templates />
</tr>
</common>
</template>
@columns: The number of columns that the heading or footing spans.
-->
<template match="heading|footing">
<common>
<xsl:param name="num-columns" />
</common>
<common formats="/latex/xelatex/">
<xsl:call-template name="generate-content-cell">
<!-- I'm slightly amazed that this actually works! -->
<xsl:with-param name="columns" select="if ( @columns ) then @columns else 1" />
<!--
We can't use generate-content-cell here because we need TH rather than TD. This is a one-off anyway.
-->
<th class="calendar">
<xsl:if test="@columns">
<xsl:attribute name="colspan">
<xsl:value-of select="@columns" />
</xsl:attribute>
</xsl:if>
<xsl:attribute name="colspan">
<xsl:value-of select="if ( @columns ) then @columns else 1" />
</xsl:attribute>
<xsl:apply-templates />
</th>
</common>
</template>
@columns: The number of columns that the note spans. Defaults to the overall number of columns passed in.
-->
<template match="note">
<common>
<xsl:param name="num-columns" />
<xsl:param name="num-columns" tunnel="yes" />
</common>
<common formats="/latex/xelatex/">
<xsl:call-template name="generate-content-cell">
<xsl:with-param name="columns" select="if ( @columns ) then @columns else xs:integer( $num-columns )" />
</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.
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 @lectures-per-week). The week number and date range are only generated for the first of these rows.
-->
<template match="week">
<common>
<xsl:param name="num-columns" />
</common>
<common formats="/latex/xelatex/">
<xsl:param name="week-column" />
<xsl:param name="date-column" />
<xsl:param name="section-column" />
<xsl:param name="lecture-column-1" />
<xsl:param name="lecture-column-2" />
<xsl:param name="reading-column" />
<xsl:param name="laboratory-column-1" />
<xsl:param name="laboratory-column-2" />
<xsl:param name="tutorial-column-1" />
<xsl:param name="tutorial-column-2" />
<xsl:param name="assessment-column" />
<xsl:param name="num-columns" tunnel="yes" />
</common>
<common formats="/latex/xelatex/">
<xsl:param name="week-column" tunnel="yes" />
<xsl:param name="date-column" tunnel="yes" />
<xsl:param name="section-column" tunnel="yes" />
<xsl:param name="lecture-column-1" tunnel="yes" />
<xsl:param name="lecture-column-2" tunnel="yes" />
<xsl:param name="reading-column" tunnel="yes" />
<xsl:param name="laboratory-column-1" tunnel="yes" />
<xsl:param name="laboratory-column-2" tunnel="yes" />
<xsl:param name="tutorial-column-1" tunnel="yes" />
<xsl:param name="tutorial-column-2" tunnel="yes" />
<xsl:param name="assessment-column" tunnel="yes" />
<xsl:for-each select="row">
<!--
Weeks that are holidays have no week number or date range, just a text description.
-->
<template match="week[@holiday]">
<common>
<xsl:param name="num-columns" />
</common>
<common formats="/latex/xelatex/">
<xsl:text>\hline\hline</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:param name="num-columns" tunnel="yes" />
</common>
<common formats="/latex/xelatex/">
<!--
Output a double \hline, *except* when we're inside a latex-calendar-break element, because the double \hline has already been done by the latex-calendar-break template.
-->
<xsl:if test="not( parent::latex-calendar-break )">
<xsl:text>\hline\hline</xsl:text>
<xsl:call-template name="newline-internal" />
</xsl:if>
<xsl:call-template name="generate-content-cell">
<xsl:with-param name="columns" select="xs:integer( $num-columns )" />
<xsl:with-param name="rows">2</xsl:with-param>
</xsl:call-template>
<xsl:text> \\</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:text>\hline\hline</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:text>\hline\hline</xsl:text>
<xsl:call-template name="newline-internal" />
</common>
<common formats="/html/xhtml/">
<tr>
<xsl:call-template name="generate-content-cell">
</common>
</template>
<!--
Generate calendar heading boilerplate, i.e., all the \begin{environment}, title, etc.
-->
<template name="generate-latex-calendar-preamble">
<common>
<xsl:param name="date-column" tunnel="yes" />
<xsl:param name="section-column" tunnel="yes" />
<xsl:param name="lecture-column-1" tunnel="yes" />
<xsl:param name="lecture-column-2" tunnel="yes" />
<xsl:param name="reading-column" tunnel="yes" />
<xsl:param name="laboratory-column-1" tunnel="yes" />
<xsl:param name="laboratory-column-2" tunnel="yes" />
<xsl:param name="tutorial-column-1" tunnel="yes" />
<xsl:param name="tutorial-column-2" tunnel="yes" />
<xsl:param name="assessment-column" tunnel="yes" />
<xsl:param name="num-columns" tunnel="yes" />
<xsl:param name="teaching-period" tunnel="yes" />
</common>
<common formats="/latex/xelatex/">
<xsl:text>\begin{center}</xsl:text>
<xsl:call-template name="newline-internal" />
<!-- TODO: Probably not if standalone! -->
<xsl:text>\begin{sideways}</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:text>\resizebox{24cm}{!}{%</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:text>\begin{tabular}{|c|c</xsl:text>
<xsl:if test="$section-column > $date-column">
<xsl:text>|c</xsl:text>
</xsl:if>
<xsl:if test="$lecture-column-1 > $section-column">
<xsl:text>|c|l</xsl:text>
</xsl:if>
<xsl:if test="$reading-column > $lecture-column-2">
<xsl:text>|c</xsl:text>
</xsl:if>
<xsl:if test="$laboratory-column-1 > $reading-column">
<xsl:text>|c|c</xsl:text>
</xsl:if>
<xsl:if test="$tutorial-column-1 > $laboratory-column-2">
<xsl:text>|c|c</xsl:text>
</xsl:if>
<xsl:if test="$assessment-column > $tutorial-column-2">
<xsl:text>|c</xsl:text>
</xsl:if>
<xsl:text>|}</xsl:text>
<xsl:call-template name="newline-internal" />
<!--
Calendar heading. We can't use generate-content-cell for this, because we're doing more complex processing of the cell contents than is possible with generate-content-cell. Here, we're calling three separate templates interspersed with text, whereas generate-content-cell can only accept a simple list of nodes to apply-templates to.
-->
<xsl:text>\multicolumn{</xsl:text>
<xsl:value-of select="$num-columns" />
<xsl:text>}{c}{\LARGE\textbf{</xsl:text>
<xsl:call-template name="PaperCode" />
<xsl:text> Teaching Calendar, </xsl:text>
<xsl:value-of select="$teaching-period" />
<xsl:text>, </xsl:text>
<xsl:call-template name="PaperYear" />
<xsl:text>}} \\</xsl:text>
<xsl:call-template name="newline-internal" />
<!--
Note that using generate-empty-cell here requires about three time as much code as just doing it inline :), but we gain in terms of output consistency.
-->
<xsl:call-template name="generate-empty-cell">
<xsl:with-param name="columns" select="xs:integer( $num-columns )" />
<xsl:with-param name="rows">1</xsl:with-param>
<xsl:with-param name="column-format">c</xsl:with-param>
</xsl:call-template>
<xsl:text> \\</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:text>\hline</xsl:text>
<xsl:call-template name="newline-internal" />
</common>
</template>
<!--
Generate calendar footing boilerplate, i.e., all the \end{environment}, etc.
-->
<template name="generate-latex-calendar-postamble">
<common formats="/latex/xelatex/">
<xsl:param name="num-columns" tunnel="yes" />
<xsl:param name="caption" tunnel="yes" />
<xsl:param name="caption-text" tunnel="yes" />
<xsl:text>\hline</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:if test="( $caption = 'yes' )">
<xsl:text>\multicolumn{</xsl:text>
<xsl:value-of select="$num-columns" />
<xsl:text>}{r}{\emph{</xsl:text>
<xsl:value-of select="if ( $caption-text != '' ) then $caption-text else 'continues over\ldots'" />
<xsl:text>}} \\</xsl:text>
<xsl:call-template name="newline-internal" />
</xsl:if>
 
<xsl:text>\end{tabular}%</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:text>}</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:text>\end{sideways}</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:text>\end{center}</xsl:text>
<xsl:call-template name="newline-internal" />
</common>
</template>
<!--
Break a calendar across pages. This is only relevant to (Xe)LaTeX. The current (following) footer is appended to the closing part of the table, and the current (preceding) header is inserted at the start of the new table.
Any child elements of the latex-calendar-break will be inserted into the table after the header.
-->
<template name="latex-calendar-break" match="latex-calendar-break">
<common formats="/latex/xelatex/">
<xsl:param name="caption" select="if ( @caption ) then @caption else 'yes'" tunnel="yes" />
<xsl:param name="caption-text" select="if ( @caption-text ) then @caption-text else ''" tunnel="yes"/>
<xsl:apply-templates select="following::footer" />
<xsl:call-template name="generate-latex-calendar-postamble" />
<xsl:call-template name="newline-internal" />
<xsl:text>\newpage</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:call-template name="generate-latex-calendar-preamble" />
<xsl:apply-templates select="preceding::header" />
<xsl:call-template name="newline-internal" />
<xsl:text>\hline\hline</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:apply-templates />
</common>
</template>
</stylesheet>