Forum How do I...?

Reset the pages (plural) counter

cmillard
I hope a new thread is appropriate here. Others have had issues applying counter-reset to various elements in their source. My problem involves using counter-reset on the "pages" counter, but counter-reset seems to be evaluated just fine.

Our printed reports contain information on multiple people. We number our pages "[page] of [pages]" and reset both counters after each person. When trying to reproduce our current reports in HTML with Prince, I'm unable to reset the "pages" counter to achieve this effect.

With the start of each new person I'm generating a footer table (static flow in @bottom) which has:
content: "Page " counter(page) " of " counter(pages);


Also with the start of each new person we display that person's primary information in a table. This table uses the class "header_visit" and I'm associating the reset-counter with this class:
.header_visit {
    counter-reset: page 1; 
    counter-reset: pages 1;
}

I should note that .header_visit appears twice in the <style> block of the page. Multiple css files are dumped into a <style> block (Prince sees no external links). The first instance is from a reusable CSS file, the second from the specific report implementation.

The counter-reset on "page" works fine, but if I put in the reset line for "pages" the entire CSS block fails. With just the reset on "page", I get:
Page 1 of 4
Page 2 of 4
Page 3 of 4
-- new person, counters reset --
Page 1 of 4

I've tried a solution suggested in another thread for the footer content:
content: "Page " counter(page) " of " target-counter(".header_visit", page);


But .header_visit doesn't seem to be working or isn't the proper way to express "the next instance of an item with class 'header_visit'." In this solution, the entire content: statement fails and I get no page numbering at all.

I can use custom counters, or I can generate a "reset div" with a unique ID for each new person, but these implementations are more cumbersome and less clean.

Is there a possibility I've missed or have I goofed up somewhere?
mikeday
At the moment we don't support resetting (or incrementing) the pages counter, as it's not clear what this would mean.

Another issue is that only one CSS property value will apply to each element, so if you want to reset two counters you need to combine them like this:
p { counter-reset: foo 1 bar 2 }

If there are two separate counter-reset rules than the one with the highest priority will override the other.
cmillard
Ah! I didn't think about the attribute only being considered once. That makes a lot of sense, thank you.

Mike, I notice that the pages counter, when reset in the middle of content, will break and begin a new page (it's documented here on the forums). Is there some sort of similar behavior with 'pages'? It seems a bit out of place to enable users to reset the 'page' counter without allowing the same flexibility with 'pages' as the two are deeply intertwined.
cmillard
Assuming I wanted to base this entirely off of the 'page' counter, how could I get this working without creating an element with a specific ID to reference target-counter to?

content: "Page " counter(page) " of " target-counter(".footerstub_visit", page);


In other words I'd like to use target-counter to give me the page the footer displays on.
This was referenced here:
http://www.princexml.com/bb/viewtopic.php?t=432
mikeday
Adding a unique ID on the footer element and referencing that with target-counter is the only way to achieve this at the moment.
cmillard
Thanks, Mike.
cmillard
I've tried a handful of solutions and I'm still unable to resolve this issue. I'm sorry to bring this up again :oops: but I'm finishing a proof-of-concept for Prince and page counter flexibility is a required feature.

I've got a table ("footerstub_visit") which is sucked up as a static flow into @bottom. This footer appears on every page and needs the ability to reset page numbers.

For example:
Page 1 of 4
Page 2 of 4
Page 3 of 4
Page 4 of 4
Page 1 of 2
Page 2 of 2

With that said, I've tried the following:

Custom counters
@page {
    counter-increment: mypages;
}

@page:first {
    counter-reset: mypages 1;
}

.footerstub_visit_pagenum {
    content: "Page " counter(page) " of " counter(mypages);
}


With this setup "mypages" doesn't increment nor is it reset to 1. I tried only using one or the other, or moving them into @bottom. I'm guessing that counters in @page aren't supported. Is this correct?

I can, of course, get the increment to work once if I associate it with a CSS class applied to the footer table or one of the elements within, but it's only applied once with the declaration of the footer table, not each time the footer appears.

Question 1: How can I get a custom counter to update with every page?


Targeted "Pages" Counter
.footerstub_visit_pagenum {
    content: "Page " counter(page) " of " target-counter("#end",page)
}

<!-- insert content -->

<div id="end">
</div>



Referenced here: http://www.princexml.com/bb/viewtopic.php?t=432

In this case, I don't get the counter at all. I tried using "end" as the footer table's ID or as the ID for an element within the footer table -- both produced the same result, the entire content: portion of .footerstub_visit_pagenum fails.

Question 2: What am I doing wrong here?


I understand that resetting "page" is useful to skip an introductory page, but don't "page" and "pages" serve effectively the same purpose? Isn't "Page X of X" an intended usage?

Question 3: Doesn't it make sense that if you reset "page" you would want to reset "pages" to keep them in sync?

Many thanks, you folks have been very helpful so far!
mikeday
The only way this will work at the moment is to place an element at the end of each section that you can use with target-counter to get the page number of the end of the section. Each element at the end of the section will need a distinct unique ID. For example:
@page {
    @bottom {
        content: "Page " counter(page) " of " target-counter(url(#end1), page)
    }
}

The above rule will work, but only for one section, where the element at the end of the section has an id of "end1". You will need a new rule for each section, as there is no way at the moment to link to "the element at the end of the current section" in a generic manner.

If it's still not working, email me (mikeday@yeslogic.com) a sample document, or I can email you a simple example demonstrating one way of doing it.

As you point out, greater flexibility with the scope of the pages counter would make this a lot easier to accomplish. We will add this to the roadmap for a future release of Prince.
cmillard
Thanks, Mike! The addition of url() made all the difference. I plugged that in and what I had worked.

The other post was using target-counter("#end" ...) -- sans url() -- which failed when I tried it, hence all my other attempts and questions.

Thanks for adding a review of this to the roadmap!
mikeday
The new beta version of Prince 7.0 includes support for resetting the pages counter, which allows more flexibility in creating documents made up of multiple independent sections.
peter-de-berdt
I see this feature is documented in the Prince 7.0 release notes, how exactly do you reset the total pages counter? It doesn't seem to be documented in the Prince 7.0 documentation (or I might just have missed it).
mikeday
Using "counter-reset: pages".
mikeday
The development roadmap has all the low-level changes, and release notes and more documentation will be forthcoming with the final release of Prince 8.0.
locilocisu
It seems that this method doesn't work when the CSS is attached to Prince (user stylesheet). I suspect it can't get to the url(''). Is there any way to get around this?
mikeday
I'm not sure what you mean, can you attach an example? (Perhaps in a new forum thread, if the topic has changed).