如何强制换行表条目

Posted

技术标签:

【中文标题】如何强制换行表条目【英文标题】:How to force wrap on table entries 【发布时间】:2011-05-20 01:03:47 【问题描述】:

我在将我的 modspecs 发布为 pdf (XSL-FO) 时遇到了问题。我的表格有问题,其中一个单元格的内容将其列溢出到下一个。如何在文本上强制中断以便创建新行?

我无法手动插入零空格字符,因为表格条目是以编程方式输入的。我正在寻找一个简单的解决方案,我可以简单地添加到 docbook_pdf.xsl(作为 xsl:param 或 xsl:attribute)

编辑: 这是我目前所在的位置:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:import href="urn:docbkx:stylesheet"/>
...(the beginning of my stylesheet for pdf generation, e.g. header and footer content stuff)
<xsl:template match="text()">
    <xsl:call-template name="intersperse-with-zero-spaces">
        <xsl:with-param name="str" select="."/>
    </xsl:call-template>
</xsl:template>
<xsl:template name="intersperse-with-zero-spaces">
    <xsl:param name="str"/>
    <xsl:variable name="spacechars">
        &#x9;&#xA;
        &#x2000;&#x2001;&#x2002;&#x2003;&#x2004;&#x2005;
        &#x2006;&#x2007;&#x2008;&#x2009;&#x200A;&#x200B;
    </xsl:variable>

    <xsl:if test="string-length($str) &gt; 0">
        <xsl:variable name="c1" select="substring($str, 1, 1)"/>
        <xsl:variable name="c2" select="substring($str, 2, 1)"/>

        <xsl:value-of select="$c1"/>
        <xsl:if test="$c2 != '' and
            not(contains($spacechars, $c1) or
            contains($spacechars, $c2))">
            <xsl:text>&#x200B;</xsl:text>
        </xsl:if>

        <xsl:call-template name="intersperse-with-zero-spaces">
            <xsl:with-param name="str" select="substring($str, 2)"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

这样,表格单元格中的长词就成功分解了!不幸的是,副作用是其他地方的普通文本(如在sextion X下)现在会分解单词,以便它们出现在单独的行中。有没有办法将上述过程隔离到表中?

【问题讨论】:

这看起来更像是一个 XSL-FO 词汇问题。我已经这样重新标记了。如果您认为是 XSLT 问题,请提供输入示例和所需输出。 @Alejandro:是的,它在技术上是一个 XSL-FO 问题(因为该问题不会在 html 中存在)。我想我希望有一种方法可以在 xml 中添加一些东西。 您想要一个将零空格字符放入文本的 XSLT 解决方案吗?如果是这样,您能否提供您的 XSL-FO 的最小可能示例以及您需要将哪些文本/位置设为可拆分? 【参考方案1】:

在长词中,尝试在允许中断的字符之间插入zero-width space character。

您可以使用 XSLT 在每个字符之间插入一个零宽度的空格。这是一种方法:http://groups.yahoo.com/neo/groups/XSL-FO/conversations/topics/1177。

这是一个邮件列表线程,其中讨论了解决问题的各种方法:http://www.stylusstudio.com/xsllist/200201/post80920.html。

SourceForge DocBook stylesheets 包含一个用于在 FO 输出中分解长 URL 的模板;见http://www.sagehill.net/docbookxsl/Ulinks.html#BreakLongUrls。模板 (hyphenate-url) 位于 xref.xsl。

【讨论】:

@mzjin:无法手动添加那个字符,因为列宽未知,并且条目本身是在运行时生成的 @mzjin:我正在使用解决方案 1,我已经非常接近了,请参阅我的答案的编辑。 您应该确保模板仅适用于表格单元格。试试&lt;xsl:template match="entry/text()"&gt; @mzjin:是因为我们缺少&lt;xsl:template match="@*|node()"&gt; 吗? @Ace,这可能是上下文问题。试试这个:&lt;xsl:template match="text()[parent::entry]"&gt;.【参考方案2】:

由于您使用的是 XSLT 2.0:

<xsl:template match="text()">
  <xsl:value-of
      select="replace(replace(., '(\PZs)(\PZs)', '$1&#x200B;$2'),
                      '([^\pZs&#x200B;])([^\pZs&#x200B;])',
                      '$1&#x200B;$2')" />
</xsl:template>

这是使用类别转义 (http://www.w3.org/TR/xmlschema-2/#nt-catEsc) 而不是要匹配的显式字符列表,但您可以这样做。它需要两个replace(),因为内部replace() 只能在每隔一个字符之间插入一个字符。外部replace() 匹配的字符既不是空格字符也不是由内部replace() 添加的字符。


在每第十三个非空格字符之后插入:

<xsl:template match="text()">
  <xsl:value-of
      select="replace(replace(., '(\PZs13)', '$1&#x200B;'),
                      '&#x200B;(\pZs)',
                      '$1')" />
</xsl:template>

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


如果您使用的是 AH Formatter,那么您可以使用axf:word-break="break-all" 来允许 AH Formatter 在单词中的任何位置进行分行。见https://www.antennahouse.com/product/ahf64/ahf-ext.html#axf.word-break。

【讨论】:

以上是关于如何强制换行表条目的主要内容,如果未能解决你的问题,请参考以下文章

css 如何控制span 强制换行

css怎么强制换行?

如何在视频的 vtt 中强制换行

vscode js属性强制换行

css实现强制不换行/自动换行/强制换行

antd中的table如何强制换行