Best way to handle multiple string replacements?

Subject: Best way to handle multiple string replacements?
From: Warren Hedley <w.hedley@xxxxxxxxxxxxxx>
Date: Mon, 05 Jun 2000 13:50:17 -0400
Hi folks

I've got some XML->LaTeX transformations and I noticed that I
keep ending up with lists of calls to string replacement
routines, with the results being stored in variables (see
following XSL). It works, but it's ugly and not particularly
elegant. Has anyone ever found a better solution?

Obviously you could use the output from one template call as
the input to the next, but this starts looking pretty bad when
you get really long lists of translations.

Does anyone have any cool templates that take a hashtable of
find and replace strings that are all applied to one piece of
input text?

I enclose some XSLT to demonstrate what I'm on about. Imagine
what a stylesheet that translates the 165-255 bytes of UTF-8
into LaTeX macros looks like.

Incidentally, does anyone know what the LaTeX macro for &#0182;
(pilcrow sign = paragraph sign) is? The best I've been able to
do is $\mathbb{P}$.


<!-- this template puts a backslash in front of each "special_char" -->
<xsl:template name="put_slash_in_front_of">
  <xsl:param name="input_text" />
  <xsl:param name="special_char" />
  <xsl:choose>
    <xsl:when test="contains($input_text, $special_char)">
      <xsl:value-of select="substring-before($input_text, $special_char)" />
      <xsl:text>\</xsl:text>
      <xsl:value-of select="$special_char" />
      <xsl:call-template name="put_slash_in_front_of">
        <xsl:with-param name="input_text"
                        select="substring-after($input_text, $special_char)" />
        <xsl:with-param name="special_char" select="$special_char" />
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$input_text" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- your standard string replace template -->
<xsl:template name="latex_string_replace">
  <xsl:param name="input_text" />
  <xsl:param name="find" />
  <xsl:param name="replace" />
  <xsl:choose>
    <xsl:when test="contains($input_text, $find)">
      <xsl:value-of select="substring-before($input_text, $find)" />
      <xsl:value-of select="$replace" />
      <xsl:call-template name="latex_string_replace">
        <xsl:with-param name="input_text"
            select="substring-after($input_text, $find)" />
        <xsl:with-param name="find"    select="$find" />
        <xsl:with-param name="replace" select="$replace" />
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$input_text" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- the ugly list of calls -->
<xsl:template name="escape_special_characters">
  <xsl:param name="input_text" />

  <xsl:variable name="step_1">
    <xsl:call-template name="put_slash_in_front_of">
      <xsl:with-param name="input_text" select="$input_text" />
      <xsl:with-param name="special_char" select="'_'" />
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="step_2">
    <xsl:call-template name="put_slash_in_front_of">
      <xsl:with-param name="input_text" select="$step_1" />
      <xsl:with-param name="special_char" select="'%'" />
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="step_3">
    <xsl:call-template name="put_slash_in_front_of">
      <xsl:with-param name="input_text" select="$step_2" />
      <xsl:with-param name="special_char" select="'$'" />
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="step_4">
    <xsl:call-template name="put_slash_in_front_of">
      <xsl:with-param name="input_text" select="$step_3" />
      <xsl:with-param name="special_char" select="'{'" />
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="step_5">
    <xsl:call-template name="put_slash_in_front_of">
      <xsl:with-param name="input_text" select="$step_4" />
      <xsl:with-param name="special_char" select="'}'" />
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="step_6">
    <xsl:call-template name="put_slash_in_front_of">
      <xsl:with-param name="input_text" select="$step_5" />
      <xsl:with-param name="special_char" select="'&amp;'" />
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="step_10">
    <xsl:call-template name="latex_string_replace">
      <xsl:with-param name="input_text" select="$step_6" />
      <xsl:with-param name="find"       select="'&#0177;'" />
      <xsl:with-param name="replace"    select="'$\pm$'" />
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="step_11">
    <xsl:call-template name="latex_string_replace">
      <xsl:with-param name="input_text" select="$step_10" />
      <xsl:with-param name="find"       select="'&#0176;'" />
      <xsl:with-param name="replace"    select="'$\degree$'" />
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="step_12">
    <xsl:call-template name="latex_string_replace">
      <xsl:with-param name="input_text" select="$step_11" />
      <xsl:with-param name="find"       select="'&#0169;'" />
      <xsl:with-param name="replace"    select="'\copyright'" />
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="step_13">
    <xsl:call-template name="latex_string_replace">
      <xsl:with-param name="input_text" select="$step_12" />
      <xsl:with-param name="find"       select="'&#0182;'" />
      <xsl:with-param name="replace"    select="'$\mathbb{P}$'" />
    </xsl:call-template>
  </xsl:variable>

  <xsl:value-of select="$step_13" />

</xsl:template>


-- 
Warren Hedley
Department of Engineering Science
Auckland University
New Zealand


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread