This is the mail archive of the docbook-apps@lists.oasis-open.org mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: AW: [docbook-apps] Programlisting strip-spaces problem


Hello Peter,

>From Thursday, October 7, 2004, 9:00:16 AM, you wrote:

Thanks, your solution seems good. But I've heard that preceding-sibling
and following-sibling affects perfomance somehow, so I've ended up
with the listing provided after the quote. It became so complicated
because of inner formatting (children) of <screen> I need to preserve.
But your solution seems to be more elegant. I'd like to know if my
bias against preceding-sibling is real? Perhaps some tests, but I
don't have any test-suite.

PK>  The following should work (I'm using it for screens):

PK>  <xsl:template match="screen/text()">
PK>    <xsl:variable name="before" select="preceding-sibling::node()"/>
PK>    <xsl:variable name="after" select="following-sibling::node()"/>

PK>    <xsl:variable name="conts" select="."/>

PK>    <xsl:variable name="contsl">
PK>      <xsl:choose>
PK>        <xsl:when test="count($before) = 0">
PK>          <xsl:call-template name="remove-lf-left">
PK>            <xsl:with-param name="astr" select="$conts"/>
PK>          </xsl:call-template>
PK>        </xsl:when>
PK>        <xsl:otherwise>
PK>          <xsl:value-of select="$conts"/>
PK>        </xsl:otherwise>
PK>      </xsl:choose>
PK>    </xsl:variable>

PK>    <xsl:variable name="contslr">
PK>      <xsl:choose>
PK>        <xsl:when test="count($after) = 0">
PK>          <xsl:call-template name="remove-ws-right">
PK>            <xsl:with-param name="astr" select="$contsl"/>
PK>          </xsl:call-template>
PK>        </xsl:when>
PK>        <xsl:otherwise>
PK>          <xsl:value-of select="$contsl"/>
PK>        </xsl:otherwise>
PK>      </xsl:choose>
PK>    </xsl:variable>

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

PK>  </xsl:template>

PK>   <!-- eats linefeeds from the left -->
PK>   <xsl:template name="remove-lf-left">
PK>     <xsl:param name="astr"/>

PK>     <xsl:choose>
PK>       <xsl:when test="starts-with($astr,'&#xA;') or
PK>                 starts-with($astr,'&#xD;')">
PK>         <xsl:call-template name="remove-lf-left">
PK>           <xsl:with-param name="astr" select="substring($astr, 2)"/>
PK>         </xsl:call-template>
PK>       </xsl:when>
PK>       <xsl:otherwise>
PK>         <xsl:value-of select="$astr"/>
PK>       </xsl:otherwise>
PK>     </xsl:choose>
PK>   </xsl:template>

PK>   <!-- eats whitespace from the right -->
PK>   <xsl:template name="remove-ws-right">
PK>     <xsl:param name="astr"/>

PK>     <xsl:variable name="last-char">
PK>       <xsl:value-of select="substring($astr, string-length($astr), 1)"/>
PK>     </xsl:variable>

PK>     <xsl:choose>
PK>       <xsl:when test="($last-char = '&#xA;') or
PK>                 ($last-char = '&#xD;') or
PK>                 ($last-char = '&#x20;') or
PK>                 ($last-char = '&#x9;')">
PK>         <xsl:call-template name="remove-ws-right">
PK>           <xsl:with-param name="astr"
PK>                           select="substring($astr, 1, string-length($astr) -
1)"/>>
PK>         </xsl:call-template>
PK>       </xsl:when>
PK>       <xsl:otherwise>
PK>         <xsl:value-of select="$astr"/>
PK>       </xsl:otherwise>
PK>     </xsl:choose>
PK>   </xsl:template>

PK> Regards
PK> Peter


  It is kind of wizardry, but when I stepped on this way I was just
unable to give up. =) It is customization of programlisting template
from verbatim.xsl of 1.66.1 DocBook XSL and recursive template to
strip newlines from end and from start of any string or from any of
these string coordinates separately.

  <xsl:template match="programlisting|screen|synopsis">
    <xsl:param name="suppress-numbers" select="'0'"/>
    <xsl:variable name="id">
      <xsl:call-template name="object.id"/>
    </xsl:variable>

    <xsl:call-template name="anchor"/>

    <xsl:variable name="content">
      <pre class="{name(.)}">
      <xsl:variable name="precontent">
        <xsl:choose>
          <xsl:when test="count(*|text()) = count(text()) = 1"><!-- only text() here -->
            <xsl:call-template name="trim_newlines"/>
          </xsl:when>

          <xsl:otherwise>                                      <!-- mixed content - process separately to keep markup tags -->
            <xsl:variable name="nameoffirst" select="local-name((*|text())[position()=1])"/>
            <xsl:if test="$nameoffirst = ''"><!-- 1st node is text() -->
              <xsl:call-template name="trim_newlines">
                <xsl:with-param name="string" select="text()[position()=1]"/>
                <xsl:with-param name="lttrim" select="true()"/>
              </xsl:call-template>
            </xsl:if>
            <xsl:choose>
              <xsl:when test="local-name((*|text())[position()=last()]) != ''"><!-- last node is not text() -->
                <xsl:if test="$nameoffirst = ''"><!-- 1st text() node is already processed -->
                   <xsl:apply-templates select="*|text()[position()!=1]"/>
                </xsl:if>
                <xsl:if test="$nameoffirst != ''"><!-- 1st text() was not processed -->
                   <xsl:apply-templates />
                </xsl:if>
              </xsl:when>
              <xsl:otherwise>
                <xsl:if test="$nameoffirst = ''"><!-- 1st text() node is already processed -->
                   <xsl:apply-templates select="*|text()[position()!=1 and position()!=last()]"/>
                </xsl:if>
                <xsl:if test="$nameoffirst != ''"><!-- 1st text() was not processed -->
                   <xsl:apply-templates select="*|text()[position()!=last()]"/>
                </xsl:if>
                <xsl:call-template name="trim_newlines">
                  <xsl:with-param name="string" select="text()[position()=last()]"/>
                  <xsl:with-param name="rttrim" select="true()"/>
                </xsl:call-template>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>

      <xsl:choose>
        <xsl:when test="$suppress-numbers = '0'
                        and @linenumbering = 'numbered'
                        and $use.extensions != '0'
                        and $linenumbering.extension != '0'">
          <xsl:call-template name="number.rtf.lines">
            <xsl:with-param name="rtf" select="$precontent"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <xsl:copy-of select="$precontent"/>
        </xsl:otherwise>
      </xsl:choose>
      </pre>
    </xsl:variable>

    <xsl:choose>
      <xsl:when test="$shade.verbatim != 0">
        <table xsl:use-attribute-sets="shade.verbatim.style">
          <tr>
            <td>
              <xsl:copy-of select="$content"/>
            </td>
          </tr>
        </table>
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy-of select="$content"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template name="trim_newlines">
    <xsl:param name="string" select="."/>
    <xsl:param name="lttrim" select="false()"/>
    <xsl:param name="rttrim" select="false()"/> <!-- looking for endstring -->

    <xsl:variable name="nl" select="'&#xA;'" />

    <xsl:choose>
      <xsl:when test="normalize-space($string) and contains($string,$nl)"><!-- prevent endless cycle on empty blocks -->
        <xsl:variable name="beforenl" select="substring-before($string,$nl)" />
        <xsl:variable name="afternl" select="substring-after($string,$nl)" />
        <xsl:variable name="nextnl" select="normalize-space(substring-before($afternl,$nl))" />
        <xsl:choose>
          <xsl:when test="not($rttrim) and string-length(normalize-space($beforenl)) = 0">
            <xsl:call-template name="trim_newlines">
              <xsl:with-param name="string" select="$afternl" />
              <xsl:with-param name="lttrim" select="$lttrim" />
              <xsl:with-param name="rttrim" select="$rttrim or $nextnl" />
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
            <xsl:copy-of select="concat($beforenl,$nl)"/>
            <xsl:if test="$lttrim">
              <xsl:copy-of select="$afternl"/>
            </xsl:if>
            <xsl:if test="not($lttrim)">
              <xsl:call-template name="trim_newlines">
                <xsl:with-param name="string" select="$afternl" />
                <xsl:with-param name="rttrim" select="true()" />
              </xsl:call-template>
            </xsl:if>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>
      <xsl:otherwise>
        <xsl:if test="normalize-space($string)">
          <xsl:copy-of select="$string"/>
        </xsl:if>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>


-- 
 TiP


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]