4

XSL-FO の動的な高さに苦労していますblock element。3 つのメイン テーブルを含むページ レイアウトを指定しました。最初のテーブルのサイズは異なる場合があります。したがって、ページで利用可能なすべてのスペースを埋めたいので、最後のテーブルも高さを変えたいと思います。テーブル #3 に含まれるブロックが使用できる最小サイズと最大サイズを指定できます。同時に、利用可能なスペースに対して長すぎる場合、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 ではありませんが、RenderX のソフトウェアを使用してそのようなソリューションを実装しました。この解決策には、テキストの場所を含むページのすべての詳細を含む XML 構造であるエリア ツリーにページをそのままフォーマットすることが含まれます。特別な拡張 (rx:pinpoint 要素) を使用して、ソース XSL FO には、コンテンツをフェザーしたい場所にこれらのマーカーが含まれます。

元のドキュメントでは、フローとフッター領域に配置された色を使用して、ページで使用可能なスペースを計算します。

このすべての情報は、エリア ツリーで利用できます。XSL を使用してエリア ツリーを変更すると、使用可能な余白を「測定」し、フェザリング ピンポイントの数で割ってから、エリア ツリーを変更して、最終出力の前に構成後のコンテンツを「移動」できます。ほとんどすべてのフォーマッタで、シリアル化されたエリア ツリーを変更し、最終出力のためにソフトウェアに戻すことができます。

以下で重要なのは、領域ツリー内の後続のすべてのコンテンツを下に移動するために使用できる xep:translate 要素を知ることです。したがって、すべての領域を「ナッジ」するには、許可されたすべての「ナッジ」ポイントにこれらのいずれかを挿入して、コンテンツを (利用可能な空白/ナッジ ポイントの数) だけ下に移動します。

使用しているフォーマッタはわかりませんが、RenderX でない場合は、必要に応じて以下を変更できるかもしれません。これは、実際にはいくつかのアプリケーションで使用されています。その目的は、ページのテキスト コンテンツが常にページの最後で終了するように、すべてのページを「フェザー」することです。

サンプルへのリンク:

http://www.tandesa.com/Public/Nudge/sf-orig.pdf (これは、ナッジが適用されなかった場合に作成される元のファイルです)

http: /利用可能なナッジ領域を計算するため)

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 に答える
2

問題は、要件として次のように述べているところです。

ページで使用可能なすべてのスペースを埋めたい

このような概念は、XSL-FO 1.x では使用できません。「ここからページの最後まで」という意味はありません。ページに残っているスペースの長さ情報を渡すための変換へのフィードバック ループはありません。

XSL-FO を使用する場合、XSL-FO ファイルを作成するときに利用可能な XSL-FO セマンティクスをやみくもに使用する必要があります。フェンスを越えてフォーマッターに渡し、フォーマッターにデータと不測の事態を処理させます。条件に対応するためにデータに入れます。

1 つのページのみを扱っている場合は、そのページにクリッピング ブロック コンテナーを配置し、そこにテーブルを流し込むことができます。最後のテーブルはページの下部まで拡張されますが、境界エッジは得られません。下部とブロック コンテナーは、テーブルの前後にコンテンツが流れません。

必要な動作がドキュメントのコンテンツの残りの部分に流れ込むことである場合、私はあなたが立ち往生していると思います.

于 2013-09-13T15:28:18.193 に答える