summaryrefslogtreecommitdiff
path: root/latex/escape.xsl
diff options
context:
space:
mode:
Diffstat (limited to 'latex/escape.xsl')
-rw-r--r--latex/escape.xsl158
1 files changed, 158 insertions, 0 deletions
diff --git a/latex/escape.xsl b/latex/escape.xsl
new file mode 100644
index 0000000..309a393
--- /dev/null
+++ b/latex/escape.xsl
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet
+ version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:output method="text"/>
+
+ <!-- In this table, the odd-numbered elements are the unicode
+ characters that need to be replaced, and the even-numbered
+ elements are the replacement strings. No space is allowed
+ within the replacement string! -->
+ <xsl:param name="patterns-table">
+ &amp; \&amp;
+ % \%
+ \ \textbackslash{}
+ è \`{e}
+ é \'{e}
+ É \'{E}
+ à \`{a}
+ î \^{i}
+ ’ '
+   ~ <!-- non-breaking space -->
+ « \og{}
+ » \fg{}
+ ν $\nu$
+ </xsl:param>
+
+ <!-- Set to 'true' to print the trace of replacements -->
+ <xsl:param name="trace-escape" select="'false'" />
+
+ <xsl:template name="escape-latex-char-try-one">
+ <xsl:param name="char" />
+ <xsl:param name="patterns" />
+ <xsl:if test="$trace-escape = 'true'">
+ <xsl:message>
+ <xsl:text> Try to reduce '</xsl:text>
+ <xsl:value-of select="$char" />
+ <xsl:text>': '</xsl:text>
+ <xsl:value-of select="$patterns" />
+ <xsl:text>'...&#xA;</xsl:text>
+ </xsl:message>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="$patterns = ''">
+ <xsl:if test="$trace-escape = 'true'">
+ <xsl:message>
+ <xsl:text> No more patterns to try.&#xA;</xsl:text>
+ </xsl:message>
+ </xsl:if>
+ <xsl:value-of select="$char" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="pattern"
+ select="substring-before($patterns, ' ')" />
+ <xsl:variable name="replacement"
+ select="substring-before(substring-after($patterns, ' '), ' ')" />
+ <xsl:variable name="other-patterns"
+ select="substring-after(substring-after($patterns, ' '), ' ')" />
+ <xsl:choose>
+ <xsl:when test="$char = $pattern">
+ <xsl:if test="$trace-escape = 'true'">
+ <xsl:message>
+ <xsl:text> Matching pattern found, producing '</xsl:text>
+ <xsl:value-of select="$replacement" />
+ <xsl:text>'&#xA;</xsl:text>
+ </xsl:message>
+ </xsl:if>
+ <xsl:value-of select="$replacement" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="escape-latex-char-try-one">
+ <xsl:with-param name="char" select="$char" />
+ <xsl:with-param name="patterns" select="$other-patterns" />
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="escape-latex-char">
+ <xsl:param name="char" />
+ <xsl:variable name="patterns">
+ <xsl:value-of select="normalize-space($patterns-table)" />
+ <xsl:text> </xsl:text> <!-- Otherwise, the last pattern won’t produce anything -->
+ </xsl:variable>
+ <xsl:if test="$trace-escape = 'true'">
+ <xsl:message>
+ <xsl:text>Escaping character '</xsl:text>
+ <xsl:value-of select="$char" />
+ <xsl:text>'...&#xA;</xsl:text>
+ </xsl:message>
+ </xsl:if>
+ <xsl:call-template name="escape-latex-char-try-one">
+ <xsl:with-param name="char" select="$char" />
+ <xsl:with-param name="patterns" select="$patterns" />
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template name="do-escape-latex">
+ <xsl:param name="str" />
+ <xsl:if test="$str != ''">
+ <xsl:call-template name="escape-latex-char">
+ <xsl:with-param name="char" select="substring($str, 1, 1)" />
+ </xsl:call-template>
+ <xsl:call-template name="do-escape-latex">
+ <xsl:with-param name="str" select="substring($str, 2)" />
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="escape-latex">
+ <xsl:param name="str" />
+ <xsl:call-template name="do-escape-latex">
+ <xsl:with-param name="str" select="normalize-space($str)" />
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="text()">
+ <xsl:variable name="final">
+ <xsl:call-template name="escape-latex">
+ <xsl:with-param name="str" select="." />
+ </xsl:call-template>
+ </xsl:variable>
+ <!-- If the node is not first and it starts with space, we need to
+ keep the first space (eg, <emph>x</emph> = y should map to
+ \textit{x} = y and not \textit{x}= y) -->
+ <xsl:variable name="first-char">
+ <xsl:value-of select="substring(., 1, 1)" />
+ </xsl:variable>
+ <xsl:variable name="last-char">
+ <xsl:value-of select="substring(., string-length(.))" />
+ </xsl:variable>
+ <xsl:variable name="first-char-space">
+ <xsl:if test="$first-char = ' ' or $first-char = '&#x9;' or $first-char = '&#xA;'">
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ </xsl:variable>
+ <xsl:variable name="last-char-space">
+ <xsl:if test="$last-char = ' ' or $last-char = '&#x9;' or $last-char = '&#xA;'">
+ <xsl:text> </xsl:text>
+ </xsl:if>
+ </xsl:variable>
+ <xsl:variable name="space-left">
+ <xsl:if test="count(preceding-sibling::*) >= 1 ">
+ <xsl:value-of select="$first-char-space" />
+ </xsl:if>
+ </xsl:variable>
+ <xsl:variable name="space-right">
+ <xsl:if test="count(following-sibling::*) >= 1 ">
+ <xsl:value-of select="$last-char-space" />
+ </xsl:if>
+ </xsl:variable>
+ <xsl:value-of select="$space-left" />
+ <xsl:value-of select="$final" />
+ <xsl:value-of select="$space-right" />
+ </xsl:template>
+</xsl:stylesheet>