| | --> |
| | |
| | +<!-- |
| | + | 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>}
</xsl:text> |
| | - <xsl:apply-templates select="*"/> |
| | + <xsl:apply-templates /> |
| | <xsl:text>\end{recipe}

</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>
</xsl:text> |
| | </xsl:for-each> |
| | <xsl:text>\end{equipment}

</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>
</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>
</xsl:text> |
| | + <xsl:apply-templates select="@label" /> |
| | <xsl:apply-templates select="ingredient"/> |
| | <xsl:text>\end{ingredients}

</xsl:text> |
 |
| | <xsl:value-of select="."/> |
| | <xsl:text>}\index{</xsl:text> |
| | - <xsl:value-of select="."/> |
| | + <xsl:apply-templates /> |
| | <xsl:text>}
</xsl:text> |
| | </xsl:template> |
| | |
| | <xsl:template match="directions[1]"> |
| | <xsl:text>\startinstructions

</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>
</xsl:text> |
| | + <xsl:apply-templates select="@label" /> |
| | <xsl:apply-templates select="step" /> |
| | <xsl:text>\end{instructions}

</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>.
</xsl:text> |
| | </xsl:template> |
| | |
| | +<!-- Eat items that do not have an existing template. --> |
| | <xsl:template match="*" /> |
| | |