4

我正在为 XSL-FO 的动态高度而苦苦挣扎block element。我指定了一个包含三个主表的页面布局。第一个表的大小可能会有所不同。因此,我希望最后一张桌子的高度也有所不同,因为我想填充页面上所有可用的空间。我可以指定表#3 中包含的块可以占用的最小和最大大小。同时,如果第三个框的内容对于可用空间来说太长,则必须删除它。

到目前为止我的代码:

<fo:table-row>
    <fo:table-cell xs:use-attribute-sets="cell-style font-size-small">
        <fo:block padding-top="3pt" padding-bottom="3pt">
            <fo:inline font-weight="bold">Label:</fo:inline>
        </fo:block>
    </fo:table-cell>

    <fo:table-cell xs:use-attribute-sets="cell-style font-size-small" >
        <fo:block-container overflow="hidden" min-height="2.1cm" max-height="4cm" padding-top="3pt" padding-bottom="3pt">
            <fo:block height="100%" keep-together.within-page="always">
                <xs:value-of select="$notes"/>
            </fo:block>
        </fo:block-container>
    </fo:table-cell>
</fo:table-row>

不幸的是,它不起作用。我没有设法避免这个块/表的分页符,同时尽可能多地显示文本($notes)。

非常感谢您的帮助!

提前致谢!

4

2 回答 2

2

问题出在您作为要求声明的地方:

我想填满页面上所有可用的空间

XSL-FO 1.x 中没有这样的概念。没有“仅从此处到页尾”的语义。没有反馈循环用于传递页面上剩余空间的长度信息的转换。

使用 XSL-FO 时,您必须盲目地使用创建 XSL-FO 文件时可用的 XSL-FO 语义,将其扔给格式化程序,然后让格式化程序处理您的数据和您遇到的意外情况放入您的数据以适应条件。

如果您只处理一个页面,那么您可以在该页面上放置一个剪贴块容器并将表格流入其中,最后一个表格将延伸到页面底部,但您不会在底部和块容器不会与表格前后的内容一起流动。

如果您想要的行为与文档的其余内容一起流动,那么我认为您被卡住了。

于 2013-09-13T15:28:18.193 回答
2

虽然这不是纯粹的 XSL FO,但我已经使用 RenderX 的软件实现了类似的解决方案。该解决方案涉及将页面格式化为区域树,这是一种 XML 结构,包含页面的所有详细信息,包括文本位置。使用特殊扩展(即 rx:pinpoint 元素),源 XSL FO 将这些标记包含在您希望羽化内容的任何位置。

原始文档使用放置在流和页脚区域中的颜色来计算页面上的可用空间。

然后,所有这些信息都在区域树中可用。使用 XSL 修改区域树,可以“测量”可用的空白空间,除以羽化点的数量,然后修改区域树以“移动”内容发布组合但在最终输出之前。大多数格式化程序都允许您修改序列化区域树,然后将其返回给软件以进行最终输出。

下面的关键是了解 xep:translate 元素,该元素可用于将区域树中的所有后续内容向下移动。因此,要“轻推”所有区域,只需在每个允许的“轻推”点插入其中一个,以将内容向下移动(可用空白/轻推点数)。

我不知道您使用的是什么格式化程序,但如果不是 RenderX,也许您可​​以修改以下内容以满足您的需要。这实际上在几个应用程序中使用,其目的是“羽化”所有页面,以便页面的文本内容始终在页面末尾结束。

样品链接:

http://www.tandesa.com/Public/Nudge/sf-orig.pdf(这是如果不应用轻推将创建的原始文件)

http://www.tandesa.com/Public/Nudge/sf-nofeather.pdf(这显示了如果在轻推之前输出区域树会是什么样子,通常没有完成,但它显示了如何使用红色/蓝色区域用于计算可用微调区域)

http://www.tandesa.com/Public/Nudge/sf-nudged.pdf(轻推的结果)

http://www.tandesa.com/Public/Nudge/nudge.xsl(以下文件为完整性)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xep="http://www.renderx.com/XEP/xep" xmlns:math="http://exslt.org/math"
extension-element-prefixes="math" version="1.0">
<xsl:param name="max-feather-percent">40</xsl:param>
<xsl:param name="body-color" select="'1.0'"/>
<xsl:param name="footer-color" select="'1.0'"/>
<xsl:template match="xep:document">
    <xsl:copy>
        <xsl:apply-templates select="@*" mode="identity-copy"/>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

<xsl:template match="xep:internal-bookmark">
    <xep:internal-bookmark>
        <xsl:apply-templates select="@*" mode="identity-copy"/>
    </xep:internal-bookmark>
</xsl:template>

<xsl:template match="xep:page">
    <xep:page>
        <xsl:apply-templates select="@*" mode="identity-copy"/>
        <!--
            1) Figure out white space
                a) Extract the y-till of the footer-color rectangle
                b) Find the smallest y-till of the body-color rectangle
                c) (b) - (a) is white space
        -->
        <xsl:variable name="headertop"
            select="number(xep:rectangle[preceding-sibling::xep:rgb-color[1][@red=$footer-color]]/@y-till)"/>
        <xsl:variable name="pagebottom"
            select="math:min(xep:rectangle[preceding-sibling::xep:rgb-color[1][@red=$body-color]]/@y-from)"/>
        <xsl:variable name="whitespace" select="$pagebottom - $headertop"/>
        <!-- 
            2) Count the nudge areas

            The nudge areas are all the pinpoints that start with "feather" *except* the first one on the page
            and possibly the last one (need to determine it a nudge ends the page then exclude it also)
            <xep:pinpoint x="90000" y="966000" value="feathersection"/>

            Current implementation only ignores the first one and not the last
        -->
        <xsl:variable name="nudgepoints"
            select="count(xep:pinpoint[starts-with(@value,'feather')]) - 1"/>
        <!-- 
            3) Calculate the nudge factor for each                
        -->
        <xsl:variable name="nudgefactor" select="$whitespace div $nudgepoints"/>
        <!-- 
            4) Determine whether the page should be feathered at all 
                a) No nudgepoints
                b) Space to compensate for is greater than max-feather-percent
        -->
        <xsl:variable name="apply-nudge">
            <xsl:choose>
                <xsl:when test="$nudgepoints = 0">
                    <xsl:text>false</xsl:text>
                </xsl:when>
                <xsl:when test="($whitespace div @height) > ($max-feather-percent div 100)">
                    <xsl:text>false</xsl:text>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:text>true</xsl:text>
                </xsl:otherwise>
            </xsl:choose>

        </xsl:variable>
        <xsl:comment> 
            headertop: <xsl:value-of select="$headertop"/>
            pagebottom: <xsl:value-of select="$pagebottom"/>
            nudgepoints: <xsl:value-of select="$nudgepoints"/>
            nudgefactor: <xsl:value-of select="$nudgefactor"/>
            headertop: <xsl:value-of select="$headertop"/>
            pagebottom: <xsl:value-of select="$pagebottom"/>
            applynudge: <xsl:value-of select="$apply-nudge"/>
        </xsl:comment>
        <xsl:apply-templates select="*" mode="identity-copy">
            <xsl:with-param name="nudgepoints" select="$nudgepoints"/>
            <xsl:with-param name="nudgefactor" select="$nudgefactor"/>
            <xsl:with-param name="apply-nudge" select="$apply-nudge"/>
        </xsl:apply-templates>
    </xep:page>
</xsl:template>

<!-- Replace proper pinpoints with xep:transform -->

<xsl:template match="xep:pinpoint[starts-with(@value,'feather')]" mode="identity-copy">
    <xsl:param name="nudgepoints"/>
    <xsl:param name="nudgefactor"/>
    <xsl:param name="apply-nudge"/>
    <xsl:if test="count(preceding-sibling::xep:pinpoint[starts-with(@value,'feather')]) > 0 and $apply-nudge = 'true'">
        <xep:translate x="0">
            <xsl:attribute name="y">
                <xsl:value-of select="-1 * $nudgefactor"/>
            </xsl:attribute>
        </xep:translate>
    </xsl:if>
</xsl:template>

<xsl:template match="xep:pinpoint[starts-with(@value,'dontfeather')]" mode="identity-copy">
    <xsl:param name="nudgepoints"/>
    <xsl:param name="nudgefactor"/>
    <xsl:param name="apply-nudge"/>
    <xsl:if test="count(preceding-sibling::xep:pinpoint[starts-with(@value,'dontfeather')]) = 0 and $apply-nudge = 'true'">
        <xep:translate x="0">
            <xsl:attribute name="y">
                <xsl:value-of select="$nudgepoints * $nudgefactor"/>
            </xsl:attribute>
        </xep:translate>
    </xsl:if>
</xsl:template>

<!-- Strip out the colored boxes -->
<xsl:template match="xep:rgb-color[@red='{$body-color}']" mode="identity-copy"/>
<xsl:template match="xep:rgb-color[@blue='{$footer-color}']" mode="identity-copy"/>
<xsl:template match="xep:rectangle[preceding-sibling::xep:rgb-color[1][@red='{$body-color}']]" mode="identity-copy"/>
<xsl:template match="xep:rectangle[preceding-sibling::xep:rgb-color[1][@blue='{$footer-color}']]" mode="identity-copy"/> 

<!-- identity copy rules -->
<xsl:template match="node() | @*" mode="identity-copy">
    <xsl:copy>
        <xsl:apply-templates select="@*" mode="identity-copy"/>
        <xsl:apply-templates select="node()" mode="identity-copy"/>
    </xsl:copy>
</xsl:template>



</xsl:stylesheet>
于 2013-09-14T19:43:31.857 回答