Re: [xsl] Tabs

Subject: Re: [xsl] Tabs
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Tue, 13 Aug 2002 10:50:03 +0100
Hi Sascha,

> Then i have to split the tabs -string somehow.

It's fairly straight-forward to step through the tabs string one by
one in a recursive template, by splitting it on the spaces:

<xsl:template name="parseTabSpec">
  <xsl:param name="string" select="string()" />
  <xsl:choose>
    <xsl:when test="contains($string, ' ')">
      ... do something with substring-before($string, ' ') ...
      <xsl:call-template name="parseTabSpec">
        <xsl:with-param name="string"
                        select="substring-after($string, ' ')" />
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      ... do something with $string ...
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

> It seems that "tabs" are exported as special chars - how do i check
> this? and what special char it IS actually?

Usually tabs are the character &#x9; -- it would surprise me if your
source used something different for a tab. You could find out by
simply copying your source document and outputting in ASCII with:

<xsl:output encoding="ASCII" />

then any non-ASCII character will be shown as a character reference.

> And how do i count them?

Assuming that the tabs appear at the start of the string, you can
count how many are at the beginning of the string by taking the
substring before the first letter of the normalized string, deleting
any spaces or line breaks, and seeing how long the remainder is:

  string-length(
    translate(
      substring-before(., substring(normalize-space(), 1, 1)),
      ' &#xD;&#xA;', ''))

If they're using a funny character rather than a tab, then you can
count them with something like:

  string-length(
    translate(
      substring-before(., substring(translate(., $tab, ''), 1, 1)),
      ' &#xD;&#xA;', ''))

>  to make a reference to the left-margin i have to
> apply to the fo:block I am actually in-
> to make the text appear like tabbed at the right place?!

So if you've worked out how many you've counted then you know how many
strings you need to step through in your tab string to know where you
are. Try something like:

<xsl:template match="run">
  ...
  <xsl:variable name="tabs" select="..." />
  <fo:block>
    <xsl:if test="$tabs">
      <fo:left-margin>
        <xsl:call-template name="parseTabSpec">
          <xsl:with-param name="string" select="$tabs" />
          <xsl:with-param name="count"
            select="string-length(translate(substring-before(.,
                      substring(normalize-space(), 1, 1)), '
                      &#xD;&#xA;', ''))" />
        </xsl:call-template>
      </fo:left-margin>
    </xsl:if>
    <xsl:apply-templates />
  </fo:block>
</xsl:template>

<xsl:template name="parseTabSpec">
  <xsl:param name="string" select="string()" />
  <xsl:param name="count" select="1" />
  <xsl:choose>
    <xsl:when test="$count > 1 and contains($string, ' ')">
      <xsl:call-template name="parseTabSpec">
        <xsl:with-param name="string"
                        select="substring-after($string, ' ')" />
        <xsl:with-param name="count" select="$count - 1" />
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <!-- get rid of the preceding 'L' -->
      <xsl:value-of select="substring($string, 2)" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

(Untested.)

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


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


Current Thread