1

我想在使用 AH Formatter 生成的 PDF 中的 14 个字符的字符串长度后强制换行。所以这是我的 xsl 代码,没有任何换行尝试:

<xsl:attribute-set name="big" use-attribute-sets="bold">
  <xsl:attribute name="font-size">38pt</xsl:attribute>
  <xsl:attribute name="line-height">28.84pt</xsl:attribute>
  <xsl:attribute name="text-align">center</xsl:attribute>
  <xsl:attribute name="letter-spacing">1mm</xsl:attribute>
</xsl:attribute-set>

<xsl:attribute-set name="small" use-attribute-sets="bold">
  <xsl:attribute name="font-size">27pt</xsl:attribute>
  <xsl:attribute name="line-height">27pt</xsl:attribute>
  <xsl:attribute name="text-align">center</xsl:attribute>
  <xsl:attribute name="letter-spacing">1mm</xsl:attribute>
</xsl:attribute-set>

<xsl:choose>
   <xsl:when test="string-length($count_cover)>=14">
      <fo:block xsl:use-attribute-sets="small">
         <xsl:apply-templates/>
      </fo:block>
    </xsl:when>
    <xsl:otherwise>          
      <fo:block xsl:use-attribute-sets="big">
         <xsl:apply-templates/>
      </fo:block>
   </xsl:otherwise>
</xsl:choose>

是否可以使用 XSL-FO 强制换行?

4

3 回答 3

2

如果标题可以转换为字符串,则可以<fo:block/>作为换行符插入。

<xsl:variable name="cover_title" as="xs:string" select="'Very Long Cover Title! Very Long Cover Title! Very Long Cover Title! '"/>
<xsl:variable name="count_cover" as="xs:integer" select="string-length($cover_title)"/>
<xsl:variable name="lf_position" as="xs:integer" select="14"/>

<xsl:template match="/">
    <xsl:choose>
        <xsl:when test="$count_cover gt $lf_position">
            <fo:block xsl:use-attribute-sets="small">
                <xsl:analyze-string select="$cover_title" regex=".{{1}}">
                    <xsl:matching-substring>
                        <xsl:value-of select="."/>
                        <xsl:if test="position() eq $lf_position">
                            <fo:block/>
                        </xsl:if>
                    </xsl:matching-substring>
                    <xsl:non-matching-substring/>
                </xsl:analyze-string>
            </fo:block>
        </xsl:when>
        <xsl:otherwise>
            <fo:block xsl:use-attribute-sets="big">
                <xsl:value-of select="$cover_title"/>
            </fo:block>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

结果:

<fo:block font-weight="bold" font-size="27pt" line-height="27pt" text-align="center" letter-spacing="1mm">Very Long Cove<fo:block/>r Title! Very Long Cover Title! Very Long Cover Title! </fo:block>

然而,这种方法忽略了单词边界和断字控制。如果您打算制作书籍封面标题,最好使用 fo:block-container 引入 AH Formatter 扩展。

  1. 使用 fo:block-container 作为封面中固定位置和大小的标题。
  2. 使用 @axf:overflow-condense=”font-size” 设置属性 @overflow="condense"。https: //www.antennahouse.com/product/ahf60/docs/ahf-ext.html#axf.overflow-condense
  3. 在 fo:block-container 中,放置存储标题内容的 fo:block。
  4. 您可以获得所需的结果,因为 AH Formatter 会根据内容量自动调整字体大小。

[例子]

<fo:block-container position="absolute" top="..." left="..." width="..." height="..." overflow="condense" axf:overflow-condense="font-size" font-size="27pt" text-align="center">
    <fo:block>
       <fo:inline>Very Long Cover Title! Very Long Cover Title! Very Long Cover Title!</fo:inline>
    </fo:block>
</fo:block-container>
于 2016-04-27T06:50:11.273 回答
2
  1. 如果您尝试断开单词(而不是例如零件编号),那么启用连字符可能会比在固定数量的字符后断开更好的结果。

  2. 您可以使用linefeed-treatment="preserve"and insert&#xA;代替,作为在使用 <xsl:value-of>注释从 XSL FO 生成的 PDF 中插入换行符的fo:block答案。你可以做什么<xsl:value-of select="replace(., '(.{14})', '$1&#xA;')" />

  3. 您可以改为在每 14 个字符之后插入一个零宽度空格 ,&#x200B;并让 AH Formatter 在零宽度空格上中断:

<xsl:template match="text()">
      <xsl:value-of
          select="replace(replace(., '(\P{Zs}{14})', '$1&#x200B;'),
                          '&#x200B;(\p{Zs})',
                          '$1')" />
</xsl:template>`

内部replace()在每 14 个非空格字符之后插入一个字符,replace()如果第 15 个字符是空格字符,外部将其修复。

如果您使用的是比例宽度字体,则某些 14 个字符的序列(例如,不包括 14 个恒定宽度的内衬号)将比其他字符占用更多或更少的宽度,因此您可能希望&#x200B;在更多字符之间插入,以便 AH Formatter可以在断线前尽量补线。

  1. 您可以使用axf:word-break="break-all"甚至在单词内启用换行符。见https://www.antennahouse.com/product/ahf63/ahf-ext.html#axf.word-break
于 2016-04-27T10:59:29.550 回答
0

您不能在 FO 中强制换行,但可以将字符串拆分为单独的 FO 块。

<xsl:choose>
  <xsl:when test="string-length($count_cover) &gt;= 14">
    <fo:block><xsl:value-of select="substring($count_cover, 1, 13)"/></fo:block>
    <fo:block><xsl:value-of select="substring($count_cover, 14)"/></fo:block>
  </when>
  <xsl:otherwise>
    <fo:block>
      <xsl:value-of select="$count_cover"/>
    </fo:block>
  </xsl:otherwise>
</xsl:choose>
于 2016-04-23T15:58:16.033 回答