- Moved sectioning and titling templates into separate modules.
- Reimplemented "generate-subs" template to use a sequence loop rather than
  recursion.
- Refactored the way section depth is calculated.
1 parent dbaaeb1 commit 32b2b8505c98e19b4fe2046a0b2bdaac5e2fabec
nstanger authored on 4 Oct 2011
Showing 4 changed files
View
445
format-master.xml
-->
<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.
@number: Whether or not to generate a section number. It makes the most logical sense for this attribute to be associated with the section element, but the section numbers are actually generated in the "section-title" template (see below). Consequently, this attribute isn't even mentioned in this template.
'yes' [default]
'no'
-->
<template name="section" match="section">
<common formats="/latex/xelatex/">
<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>
</common>
<common formats="/html/xhtml/">
<xsl:if test="@label"><a id="{@label}"></a></xsl:if>
<xsl:apply-templates />
</common>
</template>
<!-- Footnotes. -->
<include href="modules/footnotes.xml" />
<!-- "Titling" elements, e.g., title, author, date. -->
<include href="modules/titling.xml" />
 
<!-- Document preamble stuff: title, author, date. -->
<template name="preamble-title" match="document/title" mode="preamble">
<common formats="/latex/xelatex/">
<xsl:text>\title{</xsl:text>
<xsl:if test="/document/@class = 'assignment'">
<xsl:if test="$showanswers='yes'">Sample Solution for </xsl:if>
<xsl:call-template name="PaperCode" />
<xsl:text> Assignment </xsl:text>
<xsl:value-of select="/document/@sequence-number" />
<xsl:text>: \\</xsl:text>
</xsl:if>
<xsl:apply-templates />
<xsl:text>}</xsl:text>
</common>
<!--
For HTML, strip out any raw HTML 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 switching to "strip" mode.
-->
<common formats="/html/xhtml/">
<xsl:if test="( /document/@class = 'tutorial' ) or ( /document/@class = 'laboratory' ) or ( /document/@class = 'assignment' )">
<xsl:if test="$showanswers='yes'">
<xsl:choose>
<xsl:when test="( /document/@class = 'tutorial' ) or ( /document/@class = 'laboratory' )">
<xsl:text>Selected Answers for </xsl:text>
</xsl:when>
<xsl:when test="/document/@class = 'assignment'">
<xsl:text>Sample Solution for </xsl:text>
</xsl:when>
</xsl:choose>
</xsl:if>
<xsl:call-template name="PaperCode" />
<xsl:choose>
<xsl:when test="/document/@class = 'tutorial'">
<xsl:text> Tutorial </xsl:text>
</xsl:when>
<xsl:when test="/document/@class = 'laboratory'">
<xsl:text> Lab </xsl:text>
</xsl:when>
<xsl:when test="/document/@class = 'assignment'">
<xsl:text> Assignment </xsl:text>
</xsl:when>
</xsl:choose>
<xsl:value-of select="/document/@sequence-number" />
<xsl:text>: </xsl:text>
</xsl:if>
<xsl:apply-templates mode="strip" />
</common>
</template>
 
<template name="preamble-author" match="document/author" mode="preamble">
<common formats="/latex/xelatex/">\author{<xsl:apply-templates />}</common>
</template>
 
<template name="preamble-date" match="document/date" mode="preamble">
<common formats="/latex/xelatex/">\date{<xsl:apply-templates />}</common>
</template>
 
<template name="document-title" match="document/title">
<!-- Need to do something sensible for LaTeX here. -->
<common formats="/latex/xelatex/">
<!--
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?
In fact, I think that for LaTeX documents, this template isn't called at all?? Looking at xml2xslt.xsl, if the document's standalone, "preamble-title" is used, and otherwise, "chapter-title" is used.
-->
<xsl:if test="/document/@standalone = 'yes'"><xsl:apply-templates /></xsl:if>
</common>
<common formats="/html/xhtml/">
<h1>
<xsl:if test="( /document/@class = 'tutorial' ) or ( /document/@class = 'laboratory' ) or ( /document/@class = 'assignment' )">
<xsl:if test="$showanswers='yes'">
<xsl:choose>
<xsl:when test="( /document/@class = 'tutorial' ) or ( /document/@class = 'laboratory' )">
<xsl:text>Selected Answers for </xsl:text>
</xsl:when>
<xsl:when test="/document/@class = 'assignment'">
<xsl:text>Sample Solution for </xsl:text>
</xsl:when>
</xsl:choose>
</xsl:if>
<xsl:call-template name="PaperCode" />
<xsl:choose>
<xsl:when test="/document/@class = 'tutorial'">
<xsl:text> Tutorial </xsl:text>
</xsl:when>
<xsl:when test="/document/@class = 'laboratory'">
<xsl:text> Lab </xsl:text>
</xsl:when>
<xsl:when test="/document/@class = 'assignment'">
<xsl:text> Assignment </xsl:text>
</xsl:when>
</xsl:choose>
<xsl:value-of select="/document/@sequence-number" />
<xsl:text>: </xsl:text>
</xsl:if>
<xsl:apply-templates />
</h1>
</common>
</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">
<!--
TODO: For LaTeX, filling in the "INFO XXX Tutorial", etc., is currently done in the LaTeX layer in the infrastructure surrounding the \lab and \tutorial macros (i.e., it's magic). This derives from the historical origins of the handbook, and should be moved here for consistency. An initial attempt to just replace calls to \tutorial, etc., with \chapter didn't work properly, as these macros do other things as well, including internal munging of chapter handling. This Will Be Complicated :(.
-->
<common formats="/latex/xelatex/">
<xsl:choose>
<xsl:when test="/document/@class = 'tutorial'">
<xsl:text>\tutorial{</xsl:text>
</xsl:when>
<xsl:when test="/document/@class = 'laboratory'">
<xsl:text>\lab{</xsl:text>
</xsl:when>
<xsl:otherwise>
<!-- maybe we should assume that we're in a book documentclass and issue a \chapter here? -->
<xsl:text>\general{</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates />
<xsl:text>}</xsl:text>
</common>
<common formats="/html/xhtml/">
<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>
</common>
</template>
<template name="document-author" match="document/author">
<common formats="/html/xhtml/"><p><xsl:apply-templates /></p></common>
</template>
<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 to 2, which maps to 1 to 3 below due to counting ancestor section elements coming out one more than expected).
-->
<template name="generate-subs">
<common formats="/latex/xelatex/">
<xsl:param name="depth">1</xsl:param>
<xsl:if test="$depth &gt; 1">
<xsl:if test="$depth &lt; 4">
<xsl:text>sub</xsl:text>
</xsl:if>
<xsl:call-template name="generate-subs">
<xsl:with-param name="depth" select="$depth - 1" />
</xsl:call-template>
</xsl:if>
</common>
</template>
<!--
Generate section title with nested numbering, e.g., 1.1.3.
-->
<template name="section-title" match="section/title">
<common formats="/latex/xelatex/">
<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" select="count( ancestor::section )" />
</xsl:call-template>
<xsl:text>section</xsl:text>
<!--
Unnumbered section. We reference the @number attribute of the parent section element. (We are guaranteed that the parent is a section element by the match context for this template.)
-->
<xsl:if test="../@number = 'no'">
<xsl:text>*</xsl:text>
</xsl:if>
<xsl:text>{</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>
</common>
<common formats="/html/xhtml/">
<!-- 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>
<!--
Unnumbered section, as per above. Note that the sense of the test is reversed: with LaTeX we output _additional_ text to get an unnumbered section, where as with HTML, we _suppress_ the additional text (i.e., the section number, which is generated here). We also only count sections that _are_ numbered.
-->
<xsl:if test="not( ../@number ) or ( ../@number != 'no' )">
<xsl:number count="section[not( @number ) or ( @number != 'no' )]" level="multiple" format="1.1.1.1.1.1" />
<xsl:text> </xsl:text>
</xsl:if>
<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>
</common>
</template>
<!-- Sections, subsections, etc. -->
<include href="modules/sectioning.xml" />
<!-- Meta-elements. -->
<include href="modules/meta-elements.xml" />
View
4
modules/floaters.xml
</template>
<!-- A multi-part table, i.e., one that spans multiple pages. Only relevant for LaTeX, as HTML doesn't have pages. -->
<template name="multipart-table" match="table[count(part) &gt; 0]">
<template name="multipart-table" match="table[count(part) gt 0]">
<common formats="/latex/xelatex/">
<xsl:for-each select="part">
\begin{table}[p]
\centering
<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:when test="position() gt 1">
<xsl:text> \emph{(continued)}}</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text> \emph{(continues over)}}</xsl:text>
View
107
modules/sectioning.xml 0 → 100755
<?xml version="1.0" encoding="utf-8"?>
 
<!--
Generate appropriately numbered and labelled section titles.
-->
 
<stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 
 
<!--
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.
@number: Whether or not to generate a section number. It makes the most logical sense for this attribute to be associated with the section element, but the section numbers are actually generated in the "section-title" template (see below). Consequently, this attribute isn't even mentioned in this template.
'yes' [default]
'no'
-->
<template name="section" match="section">
<common formats="/latex/xelatex/">
<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>
</common>
<common formats="/html/xhtml/">
<xsl:if test="@label"><a id="{@label}"></a></xsl:if>
<xsl:apply-templates />
</common>
</template>
 
<!--
Utility template to generate some number of "sub"s so we can produce, e.g., "subsubsection" for LaTeX.
$depth: the number of repetitions (0 to 2). If zero, then the loop never executes.
-->
<template name="generate-subs">
<common formats="/latex/xelatex/">
<xsl:param name="depth">0</xsl:param>
<xsl:for-each select="1 to $depth">
<xsl:text>sub</xsl:text>
</xsl:for-each>
</common>
</template>
<!--
Generate a section title with correctly nested numbering, e.g., 1.1.3. If we were being pedantic, this should probably go in titling.xml, but I think it makes more sense here.
-->
<template name="section-title" match="section/title">
<common formats="/latex/xelatex/">
<xsl:param name="label" />
<!--
Calculate the nesting depth up front, so that we can limit it to 2 for LaTeX. Note that we have to skip counting the parent <section> element, as that's the section currently being processed. Including it would produce a minimum depth of 1, but the minimum depth in LaTeX is actually 0.
-->
<xsl:variable name="depth">
<xsl:number value="count( ../ancestor::section )" />
<xsl:if test="count( ../ancestor::section ) gt 2">2</xsl:if>
</xsl:variable>
<xsl:text>\</xsl:text>
<!-- Generate the correct number of "sub"s for LaTeX. -->
<xsl:call-template name="generate-subs">
<xsl:with-param name="depth" select="$depth" />
</xsl:call-template>
<xsl:text>section</xsl:text>
<!--
Unnumbered section. We reference the @number attribute of the parent <section> element. (We are guaranteed that the parent is a <section> element by the match context for this template.)
-->
<xsl:if test="../@number = 'no'">
<xsl:text>*</xsl:text>
</xsl:if>
<xsl:text>{</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>
</common>
<common formats="/html/xhtml/">
<!--
Calculate the nesting depth up front, so that we can limit it to 6 for HTML. Add 1 because <h1> is reserved for the main document title; section headings start at <h2>.
-->
<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>
<!--
Generate the correct level of <Hn> element based on the value of $depth. Note the use of an attribute value template to force XSLT to interpret the contents of the name attribute as a function call rather than as the element name.
-->
<xsl:element name="{concat( 'h', $depth )}">
<!--
Unnumbered section, as per above. Note that the sense of the test is reversed: with LaTeX we output _additional_ text to get an unnumbered section, where as with HTML, we _suppress_ the additional text (i.e., the section number, which is generated here). We also only count sections that _are_ numbered.
-->
<xsl:if test="not( ../@number ) or ( ../@number != 'no' )">
<xsl:number count="section[not( @number ) or ( @number != 'no' )]" level="multiple" format="1.1.1.1.1.1" />
<xsl:text> </xsl:text>
</xsl:if>
<xsl:apply-templates />
</xsl:element>
</common>
</template>
</stylesheet>
View
166
modules/titling.xml 0 → 100755
<?xml version="1.0" encoding="utf-8"?>
 
<!--
Elements for generating "titling" components, such as title, author, date, in various contexts.
-->
 
<stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 
 
<!-- Items appearing in the document "preamble", i.e., the preamble section in LaTeX and the <head> element in HTML. -->
<!-- Document title. -->
<template name="preamble-title" match="document/title" mode="preamble">
<common formats="/latex/xelatex/">
<xsl:text>\title{</xsl:text>
<xsl:if test="/document/@class = 'assignment'">
<xsl:if test="$showanswers='yes'">Sample Solution for </xsl:if>
<xsl:call-template name="PaperCode" />
<xsl:text> Assignment </xsl:text>
<xsl:value-of select="/document/@sequence-number" />
<xsl:text>: \\</xsl:text>
</xsl:if>
<xsl:apply-templates />
<xsl:text>}</xsl:text>
</common>
<!--
For the HTML title, strip out any markup (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 switching to "strip" mode.
-->
<common formats="/html/xhtml/">
<xsl:if test="( /document/@class = 'tutorial' ) or ( /document/@class = 'laboratory' ) or ( /document/@class = 'assignment' )">
<xsl:if test="$showanswers='yes'">
<xsl:choose>
<xsl:when test="( /document/@class = 'tutorial' ) or ( /document/@class = 'laboratory' )">
<xsl:text>Selected Answers for </xsl:text>
</xsl:when>
<xsl:when test="/document/@class = 'assignment'">
<xsl:text>Sample Solution for </xsl:text>
</xsl:when>
</xsl:choose>
</xsl:if>
<xsl:call-template name="PaperCode" />
<xsl:choose>
<xsl:when test="/document/@class = 'tutorial'">
<xsl:text> Tutorial </xsl:text>
</xsl:when>
<xsl:when test="/document/@class = 'laboratory'">
<xsl:text> Lab </xsl:text>
</xsl:when>
<xsl:when test="/document/@class = 'assignment'">
<xsl:text> Assignment </xsl:text>
</xsl:when>
</xsl:choose>
<xsl:value-of select="/document/@sequence-number" />
<xsl:text>: </xsl:text>
</xsl:if>
<xsl:apply-templates mode="strip" />
</common>
</template>
 
<!-- Document author. This only makes sense for LaTeX. -->
<template name="preamble-author" match="document/author" mode="preamble">
<common formats="/latex/xelatex/">\author{<xsl:apply-templates />}</common>
</template>
 
<!-- Document date. This only makes sense for LaTeX. -->
<template name="preamble-date" match="document/date" mode="preamble">
<common formats="/latex/xelatex/">\date{<xsl:apply-templates />}</common>
</template>
 
<!-- Items appearing in the document body. -->
<!-- Document title. -->
<template name="document-title" match="document/title">
<!-- Need to do something sensible for LaTeX here. -->
<common formats="/latex/xelatex/">
<!--
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?
In fact, I think that for LaTeX documents, this template isn't called at all?? Looking at xml2xslt.xsl, if the document is standalone, "preamble-title" is used, and otherwise, "chapter-title" is used.
-->
<xsl:if test="/document/@standalone = 'yes'"><xsl:apply-templates /></xsl:if>
</common>
<common formats="/html/xhtml/">
<h1>
<xsl:if test="( /document/@class = 'tutorial' ) or ( /document/@class = 'laboratory' ) or ( /document/@class = 'assignment' )">
<xsl:if test="$showanswers='yes'">
<xsl:choose>
<xsl:when test="( /document/@class = 'tutorial' ) or ( /document/@class = 'laboratory' )">
<xsl:text>Selected Answers for </xsl:text>
</xsl:when>
<xsl:when test="/document/@class = 'assignment'">
<xsl:text>Sample Solution for </xsl:text>
</xsl:when>
</xsl:choose>
</xsl:if>
<xsl:call-template name="PaperCode" />
<xsl:choose>
<xsl:when test="/document/@class = 'tutorial'">
<xsl:text> Tutorial </xsl:text>
</xsl:when>
<xsl:when test="/document/@class = 'laboratory'">
<xsl:text> Lab </xsl:text>
</xsl:when>
<xsl:when test="/document/@class = 'assignment'">
<xsl:text> Assignment </xsl:text>
</xsl:when>
</xsl:choose>
<xsl:value-of select="/document/@sequence-number" />
<xsl:text>: </xsl:text>
</xsl:if>
<xsl:apply-templates />
</h1>
</common>
</template>
 
<!-- Document author. -->
<template name="document-author" match="document/author">
<common formats="/html/xhtml/"><p><xsl:apply-templates /></p></common>
</template>
<!-- Document date. -->
<template name="document-date" match="document/date" />
 
<!--
Chapter titles 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">
<!--
TODO: For LaTeX, filling in the "INFO XXX Tutorial", etc., is currently done in the LaTeX layer in the infrastructure (coursehandbook.cls) surrounding the \lab and \tutorial macros (i.e., it's magic). This derives from the historical origins of the handbook, and should be moved here for consistency. An initial attempt to just replace calls to \tutorial, etc., with \chapter didn't work properly, as the \tutorial, etc., macros do other things as well, including internal munging of chapter handling. This Will Be Complicated :(.
-->
<common formats="/latex/xelatex/">
<xsl:choose>
<xsl:when test="/document/@class = 'tutorial'">
<xsl:text>\tutorial{</xsl:text>
</xsl:when>
<xsl:when test="/document/@class = 'laboratory'">
<xsl:text>\lab{</xsl:text>
</xsl:when>
<xsl:otherwise>
<!-- maybe we should assume that we're in a book documentclass and issue a \chapter here? -->
<xsl:text>\general{</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates />
<xsl:text>}</xsl:text>
</common>
<common formats="/html/xhtml/">
<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>
</common>
</template>
 
</stylesheet>