- Reformatted code and made consistent use of xsl:text and newline-internal.
- Added the various list elements to the collection of "paragraph-like" elements
  that shouldn't have <p></p> wrapped around them.
1 parent e162bb8 commit f76d5a5892c89cd1b0852dfa9bbe6c12d3226bf8
nstanger authored on 7 Oct 2011
Showing 1 changed file
View
116
modules/lists.xml
<!-- Unordered lists -->
<template name="itemised-list" match="itemised-list|itemize|unordered-list|bulleted-list|bullet-list|bullet-points|UL|ul">
<common formats="/latex/xelatex/">
\begin{itemize}
<xsl:apply-templates select="item" mode="normal" />
\end{itemize}
<xsl:call-template name="newline-internal" />
<xsl:text>\begin{itemize}</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:apply-templates select="item" mode="normal" />
<xsl:call-template name="newline-internal" />
<xsl:text>\end{itemize}</xsl:text>
<xsl:call-template name="newline-internal" />
</common>
<common formats="/html/xhtml/">
<ul>
<xsl:apply-templates select="item" mode="normal" />
@start: The starting number for the list. [default 1]
-->
<template name="enumerated-list" match="enumerated-list|enumerate|ordered-list|numbered-list|question-list|OL|ol">
<common formats="/latex/xelatex/">
\begin{enumerate}
<xsl:if test='@start'>
<!--
Set the appropriate enum counter according to the depth. Use the format attribute of xsl:number to output it in Roman numerals. Depth must be at least 1 (enumi) and at most 4 (enumiv). Bizarrely, a count(ancestor::xxx) here gives 0 for the outermost element, whereas for section elements it gives 1?!?!
-->
<xsl:text>\setcounter{enum</xsl:text>
<xsl:number value="min( ( 1 + count( ancestor::enumerated-list|ancestor::enumerate|ancestor::ordered-list|ancestor::numbered-list|ancestor::question-list|ancestor::OL|ancestor::ol ), 4 ) )" format="i" />
<xsl:text>}{</xsl:text>
<!-- Remember that LaTeX adds 1 to the counter before using it. -->
<xsl:value-of select="@start - 1" />
<xsl:text>}</xsl:text>
</xsl:if>
<xsl:apply-templates select="item" mode="enumerated-list" />
\end{enumerate}
<xsl:call-template name="newline-internal" />
<xsl:text>\begin{enumerate}</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:if test='@start'>
<!--
Set the appropriate enum counter according to the depth. Use the format attribute of xsl:number to output it in Roman numerals. Depth must be at least 1 (enumi) and at most 4 (enumiv).
-->
<xsl:text>\setcounter{enum</xsl:text>
<xsl:number value="min( ( 1 + count( ancestor::enumerated-list|ancestor::enumerate|ancestor::ordered-list|ancestor::numbered-list|ancestor::question-list|ancestor::OL|ancestor::ol ), 4 ) )" format="i" />
<xsl:text>}{</xsl:text>
<!-- Remember that LaTeX adds 1 to the counter before using it. -->
<xsl:value-of select="@start - 1" />
<xsl:text>}</xsl:text>
</xsl:if>
<xsl:apply-templates select="item" mode="enumerated-list" />
<xsl:call-template name="newline-internal" />
<xsl:text>\end{enumerate}</xsl:text>
<xsl:call-template name="newline-internal" />
</common>
<common formats="/html/xhtml/">
<ol>
<xsl:if test="@start">
<!-- Definition or description lists. -->
<template name="definition-list" match="definition-list|description-list|DL|dl">
<common formats="/latex/xelatex/">
\begin{description}
<xsl:apply-templates select="item" mode="definition-list" />
\end{description}
<xsl:call-template name="newline-internal" />
<xsl:text>\begin{description}</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:apply-templates select="item" mode="definition-list" />
<xsl:call-template name="newline-internal" />
<xsl:text>\end{description}</xsl:text>
<xsl:call-template name="newline-internal" />
</common>
<common formats="/html/xhtml/">
<!--
<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.
 
 
<!-- List items for non-definition lists. -->
<template name="list-item" match="item" mode="normal">
<common formats="/latex/xelatex/"><xsl:text>\item </xsl:text><xsl:apply-templates /></common>
<common formats="/latex/xelatex/">
<xsl:text>\item </xsl:text>
<xsl:apply-templates />
<xsl:call-template name="newline-internal" />
</common>
<common formats="/html/xhtml/">
<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.
-->
<xsl:when test="count(paragraph|para|p|question|answer|code-block) != 0">
Check whether there are actual paragraphs or things that should be treated like paragraphs inside the item (there are rather a lot of these!). If so, let them worry about inserting the <p> tags.
-->
<xsl:when test="count(paragraph|para|p|question|answer|code-block|itemised-list|itemize|unordered-list|bulleted-list|bullet-list|bullet-points|UL|ul|enumerated-list|enumerate|ordered-list|numbered-list|question-list|OL|ol|definition-list|description-list|DL|dl) != 0">
<li><xsl:apply-templates /></li>
</xsl:when>
<!--
Otherwise, insert <p> tags surrounding the item content so that the item spacing looks OK.
<xsl:text>}{</xsl:text>
<!-- Remember that LaTeX adds 1 to the counter before using it. -->
<xsl:value-of select="@value - 1" />
<xsl:text>}</xsl:text>
<xsl:call-template name="newline-internal" />
<xsl:apply-templates select="." mode="normal" />
</common>
<!--
Unfortunately this can't just be a wrapper around the "normal" item template because of the nesting of attributes inside the element.
-->
<common formats="/html/xhtml/">
<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.
-->
<xsl:when test="count(paragraph|para|p|question|answer|code-block) != 0">
Check whether there are actual paragraphs or things that should be treated like paragraphs inside the item (there are rather a lot of these!). If so, let them worry about inserting the <p> tags.
-->
<xsl:when test="count(paragraph|para|p|question|answer|code-block|itemised-list|itemize|unordered-list|bulleted-list|bullet-list|bullet-points|UL|ul|enumerated-list|enumerate|ordered-list|numbered-list|question-list|OL|ol|definition-list|description-list|DL|dl) != 0">
<li>
<xsl:attribute name="value" select="@value" />
<xsl:apply-templates />
</li>
<xsl:text>\item[</xsl:text>
<xsl:apply-templates select="keyword|term|topic|DT|dt" />
<xsl:text>] </xsl:text>
<xsl:apply-templates select="definition|description|discourse|DD|dd" />
<xsl:call-template name="newline-internal" />
</common>
<common formats="/html/xhtml/">
<!--
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:
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 NOT a <p> 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.
If the first sub-node of the <definition> is NOT a <p> 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(child::node()[2]/child::node()[1][self::p] or child::node()[2]/child::node()[1][self::paragraph])">
<xsl:when test="not( 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]" />
<!--
Need to provide some context here as, e.g., <term> is also a standalone element.
-->
<template name="keyword" match="item/keyword|item/term|item/topic|item/DT|item/dt">
<common formats="/latex/xelatex/"><xsl:apply-templates /></common>
<common formats="/html/xhtml/"><strong><xsl:apply-templates /></strong></common>
</template>
<common formats="/latex/xelatex/">
<xsl:apply-templates />
</common>
<common formats="/html/xhtml/">
<strong><xsl:apply-templates /></strong>
</common>
</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>
<common>
<xsl:apply-templates />
</common>
</template>
 
 
</stylesheet>