Forum How do I...?

Page references in index displaying inconsistent behaviour with varying column width

lsteward
I am using a prince-script to generate page numbers in the index of my project, and I am getting confusing and inconsistent page numbers showing in the PDF output and in the console, which seem to vary based on the width of the columns on the page.

The HTML of my index entries looks like this

<ul class="reference-index">
  <li class="index-subhead">U</li>
  <li>United States
    <ul>
      <li>inequality
        <a href="05.html#iid-1" class="from">1</a>
        <a href="05.html#iid-2" class="to">2</a>
        <a href="08.html#iid-1" class="none">3</a>
        <a href="08.html#iid-2" class="from">4</a>
        <a href="08.html#iid-3" class="to">5</a>
        <a href="08.html#iid-4" class="from">6</a>
        <a href="08.html#iid-5" class="to">7</a>
        <a href="08.html#iid-6" class="none">8</a>
        <a href="12.html#iid-1" class="from">9</a>
        <a href="12.html#iid-2" class="to">10</a>
        <a href="12.html#iid-3" class="none">11</a></li>
    </ul>
  </li>
</ul>


where I am setting the content of the anchor elements in the CSS like this

.reference-index a {
    content: prince-script(indexPageReference, target-counter(attr(href), page), 'default');

    // First number gets an en-space before it, to separate it from the index term
			
    &:first-of-type {
        content: prince-script(indexPageReference, target-counter(attr(href), page), 'first');
    }
}


and a minimal example of my Prince script function is

Prince.addScriptFunc("indexPageReference", function (page, entryPosition) {

    if (entryPosition === 'first') {
        return " " + page;
    } else {
        return ", " + page;    
    }
});


Using the simple function above, all of the page numbers are shown correctly in the PDF, whether 2, 3, or 4 columns are used on the page.

correct-values-with-duplicates.png


The issue occurs when I add logic to account for duplicate page numbers, by comparing the page number to a stored variable and returning an empty string to the content attribute when these values are the same.

var storedPageNumber = "";

Prince.addScriptFunc("indexPageReference", function (page, entryPosition) {

    // If this is the first link in a new index entry,
    // reset the storedPageNumber.
    if (entryPosition === "first") {
    
        storedPageNumber = "";
        return " " + page;
    
    } else {
        
        if (page !== storedPageNumber) {
            // This is a new value, so store it and display it
            storedPageNumber = page;
            return ", " + page;    
        } else {
            // If this page number is the same as the previous one
            return "";
        }

    } 
});


I have tried applying the prince-script directly in the style attribute of the anchor elements, as well as via the stylesheet, and the output is the same.

  • The correct values are shown when 2 columns are used:

    correct-values-shown-2-columns.png

  • The value 563 is missing when 3 columns are used:

    563-missing-3-columns.png

  • The value 370 is missing when 4 columns are used:

    370-missing-4-columns.png

Things get more confusing when I add extra functionality to account for and style page ranges (the main reason why I need a script, and can't just use the content attribute by itself)

elided-correct-values-shown-2-columns.png


elided-363-repeated-3-columns.png


elided-correct-values-shown-4-columns.png


Does anyone have any ideas as to how to resolve this? I can compile and attach the strange result of logging the page numbers to the console if required.
  1. 370-missing-4-columns.png89.9 kB
    "370" missing when columns=4
  2. 563-missing-3-columns.png101.9 kB
    "563" missing when columns=3
  3. correct-values-shown-2-columns.png98.4 kB
    Correct values shown when columns=2
  4. correct-values-with-duplicates.png66.0 kB
    All 11 pages show in the simple case
  5. elided-363-repeated-3-columns.png112.5 kB
    Elided "363" repeated when columns=3
  6. elided-correct-values-shown-2-columns.png27.7 kB
    Correct elided values when columns=2
  7. elided-correct-values-shown-4-columns.png88.2 kB
    Correct elided values when columns=4
howcome
There's a demo on how to generate ranges here:

https://css4.pub/2022/indexes/#four-pages

Perhaps you could switch to that technique to see if it fixes the problem?

Edited by howcome

mikeday
In general you cannot guarantee how many times the function will be called and the order of the calls, so if the function depends on external state and not just its arguments then the results may be unpredictable.