如何用typographer的引号(又名卷曲引号)替换双引号

时间:2009-09-02 19:31:25

标签: xslt

我需要以"打字员的引号"以编码方式替换常规双引号 <xsl:variable name="text"> <xsl:call-template name="replace-string"><!-- FYI: replace-string is a custom method that works like you would expect--> <xsl:with-param name="text" select="."/> <xsl:with-param name="replace" select="string(' &quot;')" /><!-- left quote because of space before --> <xsl:with-param name="with" select="string('“')"/> </xsl:call-template> </xsl:variable> <xsl:variable name="text2"> <xsl:call-template name="replace-string"> <xsl:with-param name="text" select="$text"/> <xsl:with-param name="replace" select="string('&quot; ')" /><!-- right quote because of space after --> <xsl:with-param name="with" select="string('”')"/> </xsl:call-template> </xsl:variable> <xsl:apply-templates select="$text2" />

我最初的想法是这样的:

{{1}}

我担心的是报价没有确定空间的情况。比如这些。

他们说“这很棒”。 我喜欢老虎(“大型大型猫科动物”)。

在知道要应用的额外规则或不同的策略之前,有没有人必须这样做?

谢谢!

3 个答案:

答案 0 :(得分:4)

无扩展功能的解决方案是:

<xsl:template name="typograpic-quotes">
  <xsl:param name="text"    select="''" />
  <xsl:param name="quote"   select="'&quot;'" />
  <xsl:param name="open"    select="'“'" />
  <xsl:param name="close"   select="'”'" />
  <xsl:param name="inquote" select="false()" />

  <xsl:choose>
    <xsl:when test="contains($text, $quote)">
      <xsl:value-of select="substring-before($text, $quote)" />
      <xsl:choose>
        <xsl:when test="$inquote">
          <xsl:value-of select="$close" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$open" />
        </xsl:otherwise>
      </xsl:choose>
      <xsl:call-template name="typograpic-quotes">
        <xsl:with-param name="text"    select="substring-after($text, $quote)" />
        <xsl:with-param name="quote"   select="$quote" />
        <xsl:with-param name="open"    select="$open" />
        <xsl:with-param name="close"   select="$close" />
        <xsl:with-param name="inquote" select="not($inquote)" />
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$text" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

毋庸置疑,输入中的不平衡报价会使其失败。

答案 1 :(得分:3)

正则表达式。

regex:replace($textVariable, '&quot;([^&quot;]*)&quot;' , 'gi', '“$1”')

没有测试过这个,但这是一个简单的方法恕我直言。你匹配所有“(任何不是零次或多次“并将其替换为你的其他印刷报价。$ 1是对第一场比赛的反向引用。这里有一些问题,如错误的嵌套文本,未关闭的引号等等,我建议这样的事情。你可以重写这个的正则表达式并测试它。

这假设您的XSLT处理器支持EXSLT扩展。

答案 2 :(得分:0)

因为我们有一些不平衡的报价。我正在做一些更实用的事情。以下似乎适用于我尝试过的所有情况。

    <!-- Get text.  All quotes defaulted to right quote -->
        <xsl:variable name="text">
            <xsl:call-template name="replace-string">
                <xsl:with-param name="text" select="."/>
                <xsl:with-param name="replace" select="string('&quot;')" />
                <xsl:with-param name="with" select="string('”')"/>
            </xsl:call-template>
        </xsl:variable>

        <!-- Turn quotes preceded by a space into left quote -->
        <xsl:variable name="text2">
            <xsl:call-template name="replace-string">
                <xsl:with-param name="text" select="$text"/>
                <xsl:with-param name="replace" select="string(' ”')" />
                <!-- right quote because of space after -->
                <xsl:with-param name="with" select="string(' “')"/>
            </xsl:call-template>
        </xsl:variable>

        <!-- Turn quotes preceded by a parenthesy into left quote -->
        <xsl:variable name="text3">
            <xsl:call-template name="replace-string">
                <xsl:with-param name="text" select="$text2"/>
                <xsl:with-param name="replace" select="string('(”')" />
                <!-- right quote because of space after -->
                <xsl:with-param name="with" select="string('(“')"/>
            </xsl:call-template>
        </xsl:variable>

        <!-- Turn quotes that are the first character in the text into left quote -->
        <!-- Note: this one is still a little funky. For some reason the first character is always whitespace.  So I am checking the second character because it is really the first. -->
        <xsl:variable name="text4" >
            <xsl:choose>
                <xsl:when test="normalize-space(substring( $text3, 2, 2 )) = string('”')">
                    <xsl:value-of select="string('“')"/>
                    <xsl:value-of select="substring($text3, 3)"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$text3"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>

        <xsl:apply-templates select="$text4" />
相关问题