字符串长度后强制换行
Force line break after string length
我想在使用 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 强制换行?
不能在 FO 中强制换行,但可以将字符串拆分为单独的 FO 块。
<xsl:choose>
<xsl:when test="string-length($count_cover) >= 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>
如果标题可以转换成字符串,可以插入<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 扩展
- 使用 fo:block-container 作为封面中固定位置和大小的标题。
- 设置属性@overflow="condense"与@axf:overflow-condense=”font-size”。
https://www.antennahouse.com/product/ahf60/docs/ahf-ext.html#axf.overflow-condense
- 在 fo:block-container 中,放置 fo:block 存储标题内容。
- 您可以得到想要的结果,因为 AH Formatter 会根据内容量自动调整 font-size。
[示例]
<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>
如果您试图打断单词(而不是,例如,部件号),那么启用连字可能会比在固定数量的字符后打断更好的结果。
您可以使用 linefeed-treatment="preserve"
并插入 

而不是 fo:block
,作为对 Inserting a line break in a PDF generated from XSL FO using <xsl:value-of> 注释的回答。你可以用 <xsl:value-of select="replace(., '(.{14})', '
')" />
您可以改为在每第 14 个字符后插入一个零宽度 space、​
,并让 AH Formatter 在零宽度 space 处中断:
<xsl:template match="text()">
<xsl:value-of
select="replace(replace(., '(\P{Zs}{14})', '​'),
'​(\p{Zs})',
'')" />
</xsl:template>`
内部 replace()
在每 14 个非 space 字符后插入字符,如果第 15 个字符是 space 字符,则外部 replace()
修复它。
如果您使用的是比例宽度字体,一些 14 个字符的序列(不包括,例如,14 个等宽内衬数字)将比其他序列占用更多或更少的宽度,因此您可能需要插入 ​
在更多字符之间,以便 AH Formatter 可以在中断之前尽最大努力填充行。
- 您可以使用
axf:word-break="break-all"
启用单词内的换行。参见 https://www.antennahouse.com/product/ahf63/ahf-ext.html#axf.word-break
我想在使用 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 强制换行?
不能在 FO 中强制换行,但可以将字符串拆分为单独的 FO 块。
<xsl:choose>
<xsl:when test="string-length($count_cover) >= 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>
如果标题可以转换成字符串,可以插入<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 扩展- 使用 fo:block-container 作为封面中固定位置和大小的标题。
- 设置属性@overflow="condense"与@axf:overflow-condense=”font-size”。 https://www.antennahouse.com/product/ahf60/docs/ahf-ext.html#axf.overflow-condense
- 在 fo:block-container 中,放置 fo:block 存储标题内容。
- 您可以得到想要的结果,因为 AH Formatter 会根据内容量自动调整 font-size。
[示例]
<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>
如果您试图打断单词(而不是,例如,部件号),那么启用连字可能会比在固定数量的字符后打断更好的结果。
您可以使用
linefeed-treatment="preserve"
并插入

而不是fo:block
,作为对 Inserting a line break in a PDF generated from XSL FO using <xsl:value-of> 注释的回答。你可以用<xsl:value-of select="replace(., '(.{14})', '
')" />
您可以改为在每第 14 个字符后插入一个零宽度 space、
​
,并让 AH Formatter 在零宽度 space 处中断:
<xsl:template match="text()">
<xsl:value-of
select="replace(replace(., '(\P{Zs}{14})', '​'),
'​(\p{Zs})',
'')" />
</xsl:template>`
内部 replace()
在每 14 个非 space 字符后插入字符,如果第 15 个字符是 space 字符,则外部 replace()
修复它。
如果您使用的是比例宽度字体,一些 14 个字符的序列(不包括,例如,14 个等宽内衬数字)将比其他序列占用更多或更少的宽度,因此您可能需要插入 ​
在更多字符之间,以便 AH Formatter 可以在中断之前尽最大努力填充行。
- 您可以使用
axf:word-break="break-all"
启用单词内的换行。参见 https://www.antennahouse.com/product/ahf63/ahf-ext.html#axf.word-break