Index Layout

1. Table of contents
2. Index layout
3. Duplicate Index Entries
4. Index problem, how to get total string length.
5. Index layout
6. Table of Contents (or Index) layout


Table of contents

W. Eliot Kimber

> I am building a table of contents and the table of contents itself is 
> a bit fudgy.
> it looks like this:

The trick for this type of structure is to use leader-length="auto" and text-align-last="justify" on the containing block. This causes the leader to take all the available space on the line between the text before it and the text after it, which is justified to the end edge of the block.

Saying leader-length="100%" means "make the leader as long as the width of my containing region, which is not what you want.


Index layout

Bob Stayton and Ken Holman

> I'm trying to create a TOC showing the titles and page numbers with
> leader dots between.  My problem is if I have a long title that should
> go to the next line (but fits if forced) is going over into my page
> number column.  I need to have the title column at a set width.
> Example:
> Title 1............  1
> Title 2 that is long..
>                      2
> Title 3............  3

You want to add end-indent="5mm" and last-line-end-indent="-5mm".

These two will cancel each other out if there is only one line. But if there are two lines, the top one is right indented by 5mm, and the page number on the second line reaches the right margin.

Ken adds, I usually also have an outdent on the first line as well as the last line so I do a start-indent to wrap lines other than the first line and a text-indent of an equivalent negative value for the first line to start at the edge of the page.

> Also, is there any way to have the TOC adjust the leader dots for the
> amount of number contained in the page number column.  Right now, if I
> have a single-digit above a 2-digit page number, the leader dots do not
> end in the same spot.
> Example:
> Title 1.............  1
> Title 2............  10

Ken answers this with:

Use a fixed-width inline-container at the end of the line and then inside of that an end-aligned page number. You'll have to ensure no vertical shifting of the page number by tightening up the line height.

An example below

<?xml version="1.0" encoding="iso-8859-1"?><!>
<root xmlns=""
       font-family="Times" font-size="20pt">

     <simple-page-master master-name="frame"
                         page-height="297mm" page-width="210mm"
                         margin-top="15mm" margin-bottom="15mm"
                         margin-left="40mm" margin-right="40mm">
       <region-body region-name="frame-body"/>

   <page-sequence master-reference="frame">
     <flow flow-name="frame-body" xmlns="">
       <block start-indent="3cm" text-indent="-3cm"
              end-indent="3cm" last-line-end-indent="-3cm"
         This is a test of a toc entry that is very long and does not
         use any alignment for the body of the entry
         <leader leader-pattern="dots"/>
         <inline-container line-height="1" width="1.5cm">
           <block text-align-last="end">1</block>
       <block start-indent="3cm" text-indent="-3cm"
              end-indent="3cm" last-line-end-indent="-3cm"
              text-align-last="justify" text-align="justify">
         This is a second toc entry that is very long but also aligned
         in the body of the entry to get a smooth right edge
         <leader leader-pattern="dots"/>
         <inline-container line-height="1" width="1.5cm">
           <block text-align-last="end">111</block>


Duplicate Index Entries

Nikolai Grigoriev

> 5. I have an index in this manual. I have managed to set it up to
> automatically gett all the appropriate entries and have also managed to
> the page references for each word and comma delimit them, but I cannot
> to get rid of the duplicated page references. Is there any way of only
> returning unique page numbers using the fo:page-number-citation element or
> any way of removing the duplications? I have references of the form:

One of the toughest problems. No clean solution in XSL FO (unless I am missing something). I know a method to achieve this with our formatter, XEP;

but it relies upon formatter-specific tricks that permit to access the XML representation of the text already laid out.


Index problem, how to get total string length.


> If I have the following snippet:

> <fo:block margin-right="{concat(NNN*1.5),'mm')}">
> --------------------------------^^^
>    <xsl:call-template name="process-nodes"/>
>    <xsl:if test="not(@no-pg-num)">
>        <fo:leader leader-pattern="dots" leader-pattern-width="2.0mm"
> leader-alignment="reference-area"/>
>    </xsl:if>
>    <xsl:for-each
> select="document(concat($libname,'/index.xml'))//index/index-term[@id =
> $primary]">
>       <xsl:value-of select="."/><xsl:if test="position() !=
> last()">,&nbsp;</xsl:if>
>    </xsl:for-each>
> </fo:block>

> In the for-each line I grab each index-term that has 
> an id that matches the
> value in $primary.  Thus I could have a line like
>    the index entry..........123, 234, 345

> What I want to be able to do is, using the example in the line above,
> calculate the number of characters in "123, 234, 345" and 
> be able to insert
> it in the NNN location in the block margin-right location.  
> Obviously I need to figure this out outside/before the block, 
> but howto, that's the question.

This appears to be really easy: put it into a variable and use string-length:

<xsl:variable name="page-list">
       '/index.xml'))//index/index-term[@id = $primary]">
       <xsl:value-of select="."/><xsl:if test="position() !=

<fo:block margin-right="{concat(string-length($page-list)*1.5),'mm')}">
    <xsl:call-template name="process-nodes"/>
    <xsl:if test="not(@no-pg-num)">
        <fo:leader leader-pattern="dots" leader-pattern-width="2.0mm"
    <xsl:value-of select="$page-list"/>

If you have any markup in the page number list, like fo:basic-links, use xsl:copy-of instead of xsl:value-of.


Index layout

Ken Holman

>Desired layout is
>[date][free text field, long or short][leader][amount] I.e. typical 
>index formatting.
>12 Nov short free text ................... 12.50
>13 Nov long free text which causes a wrap
>        to here ........................... 13.50
>14 Nov the nasty one with just enough txt.
>                                            14.50
>I.e. the text is just enough to cause the wrap,
>     yet the leader is on the first line.
>How to manage the line wrap.

I recommend using outdents on both the first and last line, using indents for the wrap edge positions, thus ensuring your desired gaps in a single formatting object:

For example, the simplest would be:

<fo:block font-size="18pt" font-weight="normal"
          space-before="1em" start-indent="4.5em" text-indent="-4.5em"
          text-align-last="justify" end-indent="4.5em"
          padding-end="1em"/>PAYMENT,  THANK YOU. Add lots more
          content to 
               make it flow<fo:leader font-size="8pt"


Table of Contents (or Index) layout


>I have code  which formats a table of contents with the chapter 
>title, followed by a dotted leader, and the page number on the 
>right. In rare cases when the title of the chapter is a little too long, 
>but not long enough to wrap itself, I end up with a situation where the 
>title will be followed by one or two dots of the leader, then the page 
>number will be wrapped to the next line, where it is not right-justified, but 
>justified (which leads to digits in the page number being spread across 
>the whole line). Has anyone hit this problem before, and if so, can you 
>suggest a solution?

You could set letter-spacing="0" on the page-number-citation element:

<fo:block text-align="left" 
 text-align-last="justify">Section title
    <fo:leader leader-pattern="dots"/>
      ref-id="div47132" letter-spacing="0"/>

Alternatively/additionally, you could insert a non-breaking space (0xa0) between leader and page-number-citation to force the leader to keep on the same line as the page number. The leader will be stretched rather than the generated page number. Of course, you will observe a little space between leader and page number. Inserting a zero-width joiner (0x200d) instead of the non-breaking space could solve this, but then the 'text-align-last="justify"' is not always honoured (with XEP 3.8). Setting an additional end-indent on the block save for the last line may improve the result (at least we think so: the last "word" of a title then often wraps as well), e.g. in the following:

<fo:block text-align-last="justify" 
          last-line-end-indent="-12pt">Section title
 <fo:leader leader-pattern="dots"/>&#xa0;<fo:page-number-citation
ref-id="div47132" letter-spacing="0"/>