Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/recipe-books.git

Added code to enable escaping of user-defined text.

AuthorDave Jarvis <email>
Date2013-02-08 20:02:31 GMT-0800
Commit00117ddbb6af93a3666ad0831c9b6d937fdfaa5c
Parent470b78c
xsl/latex.xsl
-->
+<!--
+ | Provides output escaping around user-defined text. This ensures that
+ | users cannot embed malicious LaTeX code inside their recipes.
+ |
+ | All text that needs to be escaped ultimately is transformed through this
+ | template.
+ |
+ | @param e - The string to escape.
+ | @see http://stackoverflow.com/a/2627303/59087
+ +-->
+<xsl:template name="escape">
+ <xsl:param name="e" />
+
+ <xsl:value-of select="$e" />
+</xsl:template>
+
+<!--
+ | Normalizes and capitalizes all the words of an escaped string.
+ |
+ | @param ec - The string to normalize, capitalize, and escape.
+ +-->
+<xsl:template name="escape-capitalize">
+ <xsl:param name="ec" />
+
+ <xsl:variable name="escaped">
+ <xsl:call-template name="escape">
+ <xsl:with-param name="e" select="$ec" />
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:value-of select="normalize-space(string:capitalize-words($escaped))" />
+</xsl:template>
+
+<xsl:template match="text()" mode="escape">
+ <xsl:call-template name="escape">
+ <xsl:with-param name="e" select="." />
+ </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="text()" mode="escape-capitalize">
+ <xsl:call-template name="escape-capitalize">
+ <xsl:with-param name="ec" select="." />
+ </xsl:call-template>
+</xsl:template>
+
<xsl:template match="/" >
<xsl:apply-templates />
<xsl:template match="recipe">
<xsl:text>\begin{recipe}{</xsl:text>
- <xsl:value-of select="normalize-space(string:capitalize-words(description/title))" />
+ <xsl:apply-templates select="description/title" />
<xsl:text>}&#xa;</xsl:text>
- <xsl:apply-templates select="*"/>
+ <xsl:apply-templates />
<xsl:text>\end{recipe}&#xa;&#xa;</xsl:text>
+</xsl:template>
+
+<xsl:template match="description/title">
+ <xsl:apply-templates mode="escape-capitalize" />
</xsl:template>
<xsl:template match="preparation">
- <xsl:apply-templates select="*"/>
+ <xsl:apply-templates />
</xsl:template>
<xsl:for-each select="*[child::*]">
<xsl:text> \item[</xsl:text>
- <xsl:value-of select="normalize-space(string:capitalize-words(name()))" />
+ <xsl:call-template name="escape-capitalize">
+ <xsl:with-param name="ec" select="name()" />
+ </xsl:call-template>
<xsl:text>] </xsl:text>
- <xsl:value-of select="normalize-space(string:capitalize-words(.))" />
+ <xsl:call-template name="escape-capitalize">
+ <xsl:with-param name="ec" select="." />
+ </xsl:call-template>
<xsl:text>&#xa;</xsl:text>
</xsl:for-each>
<xsl:text>\end{equipment}&#xa;&#xa;</xsl:text>
+</xsl:template>
+
+<!--
+ | Puts the value of all labels (ingredients and directions) in brackets.
+ +-->
+<xsl:template match="@label">
+ <xsl:text>[</xsl:text>
+ <xsl:call-template name="escape-capitalize">
+ <xsl:with-param name="ec" select="." />
+ </xsl:call-template>
+ <xsl:text>]</xsl:text>
+ <xsl:text>&#xa;</xsl:text>
</xsl:template>
<xsl:template match="ingredients[descendant::text()]">
<xsl:text>\begin{ingredients}</xsl:text>
- <xsl:if test="@label">
- <xsl:text>[</xsl:text>
- <xsl:value-of select="normalize-space(string:capitalize-words(@label))"/>
- <xsl:text>]</xsl:text>
- </xsl:if>
- <xsl:text>&#xa;</xsl:text>
+ <xsl:apply-templates select="@label" />
<xsl:apply-templates select="ingredient"/>
<xsl:text>\end{ingredients}&#xa;&#xa;</xsl:text>
<xsl:value-of select="."/>
<xsl:text>}\index{</xsl:text>
- <xsl:value-of select="."/>
+ <xsl:apply-templates />
<xsl:text>}&#xa;</xsl:text>
</xsl:template>
<xsl:template match="directions[1]">
<xsl:text>\startinstructions&#xa;&#xa;</xsl:text>
</xsl:template>
<xsl:template match="directions[descendant::text()]">
<xsl:text>\begin{instructions}</xsl:text>
- <xsl:if test="@label">
- <xsl:text>[</xsl:text>
- <xsl:value-of select="normalize-space(string:capitalize-words(@label))"/>
- <xsl:text>]</xsl:text>
- </xsl:if>
- <xsl:text>&#xa;</xsl:text>
+ <xsl:apply-templates select="@label" />
<xsl:apply-templates select="step" />
<xsl:text>\end{instructions}&#xa;&#xa;</xsl:text>
</xsl:template>
<xsl:template match="step">
<xsl:text> \item </xsl:text>
<xsl:value-of select="normalize-space(string:capitalize(@action))" />
<xsl:text> </xsl:text>
- <xsl:value-of select="." />
+ <xsl:apply-templates mode="escape" />
<xsl:text>.&#xa;</xsl:text>
</xsl:template>
+<!-- Eat items that do not have an existing template. -->
<xsl:template match="*" />
Delta75 lines added, 19 lines removed, 56-line increase