xsl-fo - 连字符 block 中没有连字符

标签 xsl-fo apache-fop hyphenation

是否有可能在 fo:block 中禁用文本片段的断字? 我的问题是无法设置 hyphenate="false" 在 fo:inline 上,因为它不是属性。 fo:block 里面的 fo:block 创建了一个新行...

Fo-例子:

<fo:block hyphenate="true">
This text should be hyphenated <fo:inline hyphenate="false">This text shouldn’t be hyphenated</fo:inline>
</fo:block>

更新:

我尝试了@DanielNorberg 发布的解决方案,因为所有解决方案都无法正常工作。这似乎是一种解决方法,但仍然没有提供我想要的输出。

我使用这个模板:

<xsl:template match="text()[ancestor::span[@class='nobreak']]">
    <xsl:param name="text"><xsl:value-of select="." /></xsl:param>
    <fo:inline hyphenate="false" color="red">
        <xsl:for-each select="tokenize(replace(replace($text,'(.)','$1\\n'),'\\n$',''),'\\n')">
        <fo:inline keep-with-next.within-line="always">
            <xsl:value-of select="."/>
            <fo:character font-size="0pt">
                <xsl:value-of select="' '" />
            </fo:character>
        </fo:inline>
        </xsl:for-each>
    </fo:inline>
</xsl:template>

fo部分是这样的

<fo:block xmlns:fn="http://www.w3.org/2005/xpath-functions" space-after="14pt">
    <fo:block text-align-last="left" font-size="10pt" color="black" text-align="justify"
        font-family="ITCFranklinGothicStd-Book" line-height="14pt" wrap-option="wrap">
        <fo:block hyphenate="true" xml:lang="de">
            <fo:block>Die Entwicklung der folgenden Jahre bestätigte unsere Auffassung. Nicht nur erwiesen
                sich die <fo:inline hyphenate="false" color="red">
                    <fo:inline keep-with-next.within-line="always">T<fo:character font-size="0pt"> </fo:character></fo:inline>
                    <fo:inline keep-with-next.within-line="always">r<fo:character font-size="0pt"> </fo:character></fo:inline>
                    <fo:inline keep-with-next.within-line="always">e<fo:character font-size="0pt"> </fo:character></fo:inline>
                    <fo:inline keep-with-next.within-line="always">i<fo:character font-size="0pt"> </fo:character></fo:inline>
                    <fo:inline keep-with-next.within-line="always">b<fo:character font-size="0pt"> </fo:character></fo:inline>
                    <fo:inline keep-with-next.within-line="always">e<fo:character font-size="0pt"> </fo:character></fo:inline>
                    <fo:inline keep-with-next.within-line="always">r<fo:character font-size="0pt"> </fo:character></fo:inline>
                </fo:inline>
            </fo:block>
        </fo:block>
    </fo:block>
</fo:block>

所以“Treiber”这个词不应该连字符。但 PDF 输出如下所示:

"Treiber" is still some sort of hyphenated

解决方案更新: 对我有用的最终解决方法与上面的模板类似,但在每个字符之间添加了一个不间断空格 (⁠)。

<xsl:template match="text()[ancestor::span[@class='nobreak']]">
    <xsl:param name="text"><xsl:value-of select="replace(., ' ', '&#160;')" /></xsl:param>
    <fo:inline>
        <xsl:for-each select="tokenize(replace(replace($text,'(.)','$1\\n'),'\\n$',''),'\\n')">
        <fo:inline>
            <xsl:value-of select="."/>
            <!-- non-breaking invisible space after each character-->
            <fo:inline>&#8288;</fo:inline>
        </fo:inline>
        </xsl:for-each>
    </fo:inline>
</xsl:template>

非常感谢@DanielNorberg

最佳答案

我为此找到了解决方案(针对 FOP 2.2 进行了验证)。代码“禁用”断字并将内联内容保持在同一行。这当然是一种 hack,不能保证适用于以后的版本,但它适用于我的目的,也许它也可以帮助你。

示例 XML:

<block>Lorem ipsum <inline class='nobreak>This is neither hyphenated or line broken</inline>.</block>

XSLT 2.0 解决方案:

创建父内联元素(XSLT 1.0 和 2.0):

<xsl:template match="inline[@class='nobreak"]">
   <fo:inline>
      <xsl:apply-templates />
   </fo:inline>
</xsl:template>

“禁用”连字符并使文本内容保持在同一行(XSLT 2.0):

<xsl:template match="text()[ancestor::inline[@class='nobreak']]">
    <xsl:param name="text"><xsl:value-of select="." /></xsl:param>
    <xsl:for-each select="tokenize(replace(replace($text,'(.)','$1\\n'),'\\n$',''),'\\n')">
       <fo:inline keep-with-next.within-line="always">
          <xsl:value-of select="."/>
          <fo:character font-size="0pt">
             <xsl:value-of select="' '" />
          </fo:character>
       </fo:inline>
    </xsl:for-each>
</xsl:template>

更新 XSLT 2.0,这似乎更好:

<xsl:template match="text()[ancestor::phrase[@class='nobreak']]">
    <xsl:param name="text"><xsl:value-of select="replace(., ' ', '&#160;')" /></xsl:param>
    <xsl:for-each select="tokenize(replace(replace($text,'(.)','$1\\n'),'\\n$',''),'\\n')">
       <fo:inline>
          <xsl:value-of select="."/>
          <fo:inline font-size="0pt">
             <xsl:value-of select="'$'" />
          </fo:inline>
       </fo:inline>
    </xsl:for-each>
</xsl:template>

如果您需要一个 XSLT 1.0 解决方案,您可以轻松地在 Web 上找到一次解析文本一个字符的代码。

关于xsl-fo - 连字符 block 中没有连字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59845360/

相关文章:

xsl-fo - 在 XSL 的文本内容中保留换行符等,但不在标签本身中

osgi - FOP/AEM : Deserialization not allowed for class org. apache.fop.fonts.FontCache

javascript - 使用 hyphenator.js 在 dompdf 中进行连字符

javascript - 有没有办法从 `<div>` 元素中提取单行?

xml - 为什么我的图像没有显示在 XSL-FO 中?

xml - XSL-FO 测试 <fo :page-number/> 的值

xml - 我在哪里可以找到关于 XSL-FO(格式化/ed 对象)的好教程,这些教程是用于 fop 和获取 PDF 的?

java - 在 Oracle 数据库中使用 Apache FOP 生成包含 SVG 图像的 PDF

java - 如何通过iText7配置连字符?

页眉和页脚 XSL FO