Adam Arold
Adam Arold

Reputation: 30528

How to handle indents of very long fo:list-item-labels?

I have the following fo markup:

<fo:list-block>
    <fo:list-item>
        <fo:list-item-label end-indent="label-end()">
            <fo:block>[KEY]</fo:block>
        </fo:list-item-label>
        <fo:list-item-body start-indent="body-start()">
            <fo:block>Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah 
            Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah </fo:block>
        </fo:list-item-body>
    </fo:list-item>
</fo:list-block>

While this looks fine in print but if I change it to:

<fo:list-block>
    <fo:list-item>
        <fo:list-item-label end-indent="label-end()">
            <fo:block>[VERYLONGKEY]</fo:block>
        </fo:list-item-label>
        <fo:list-item-body start-indent="body-start()">
            <fo:block>Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah 
            Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah </fo:block>
        </fo:list-item-body>
    </fo:list-item>
</fo:list-block>

the fo:list-item-label and the following fo:list-item-body overlap. How can I set the start-indent and end-indent to use the actual width of my labels? Currently it seems that label-end() and body-start() is a constant but I would like to have a dynamic label width. Is this possible in xsl-fo?

Upvotes: 3

Views: 1845

Answers (2)

Kevin Brown
Kevin Brown

Reputation: 8877

You need to know the length of your longest label to do that. If you do you set the provisional-distance-between-starts to accommodate it. This is no different than any Word Processor where you would set the indent. Given the known length of your longest indent required and you what it all on one line, set that attribute to hold space for your label. For example, if your label is about 100pt then:

       <fo:list-block provisional-distance-between-starts="100pt" provisional-label-separation="3pt">
            <fo:list-item>
                <fo:list-item-label end-indent="label-end()">
                    <fo:block>A.</fo:block>
                </fo:list-item-label>
                <fo:list-item-body start-indent="body-start()">
                    <fo:block>Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah 
                        Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah </fo:block>
                </fo:list-item-body>
            </fo:list-item>
            <fo:list-item>
                <fo:list-item-label end-indent="label-end()">
                    <fo:block>[VERYLONGKEY]</fo:block>
                </fo:list-item-label>
                <fo:list-item-body start-indent="body-start()">
                    <fo:block>Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah 
                        Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah </fo:block>
                </fo:list-item-body>
            </fo:list-item>
        </fo:list-block>

Yields the following:

enter image description here

And note this is only required because your string [VERYLONGKEY] has no break points. If you set the provisional-distance-between-starts and your label is something like "I am a label that is very long and I should wrap" it would wrap.

Like this:

         <fo:list-block provisional-distance-between-starts="100pt" provisional-label-separation="3pt">
            <fo:list-item>
                <fo:list-item-label end-indent="label-end()">
                    <fo:block>A.</fo:block>
                </fo:list-item-label>
                <fo:list-item-body start-indent="body-start()">
                    <fo:block>Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah 
                        Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah </fo:block>
                </fo:list-item-body>
            </fo:list-item>
            <fo:list-item>
                <fo:list-item-label end-indent="label-end()">
                    <fo:block>[VERYLONGKEY]</fo:block>
                </fo:list-item-label>
                <fo:list-item-body start-indent="body-start()">
                    <fo:block>Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah 
                        Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah </fo:block>
                </fo:list-item-body>
            </fo:list-item>
            <fo:list-item>
                <fo:list-item-label end-indent="label-end()">
                    <fo:block>I am a label that is very long and I should wrap</fo:block>
                </fo:list-item-label>
                <fo:list-item-body start-indent="body-start()">
                    <fo:block>Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah 
                        Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah </fo:block>
                </fo:list-item-body>
            </fo:list-item>
        </fo:list-block>

enter image description here

Upvotes: 3

Tony Graham
Tony Graham

Reputation: 8068

It's not strictly possible in XSL 1.1.

If FOP supported automatic table layout, you could have fudged it by using a two-column table for the labels and the bodies.

You may also be able to fudge it per-list-item by using an fo:inline-container for the contents of the list item's body, but fo:inline-container support in FOP is currently said to be limited (see http://xmlgraphics.apache.org/fop/compliance.html).

You can, however, use the XSLT Extensions from the Print & Page Layout Community Group to get a FOP area tree so that you can make decisions based on formatted sizes. There's examples of using the extensions to set list indents at https://www.w3.org/community/ppl/wiki/XSLTExtensions#Example_4_-_List_item_label_width and https://www.w3.org/community/ppl/2015/02/18/getting-an-area-tree-within-your-xslt-transform/.

Upvotes: 1

Related Questions