Forum How do I...?

Multiple Page Counters - Document Pages and Chapter Pages

GreenRaccoon23
I am using Prince 12.

Is it possible to create two page counters?

In my use case, I need a page counter for the whole document and another within each chapter. For example, say chapter 2 starts on page 4 of the document, the document page counter would be at "4" and the chapter page counter would be at "1".

Is this possible with Prince?

I am currently doing this in order to get the chapter page counter:
<style type="text/css">
	.chapter {
		page: chapter;
		counter-reset: page 1;
		prince-page-group: start;
	}
	.chapter-page::after {content: counter(page);}
</style>

<body>
	<div class="chapter" id="chapter-1">
		<h1>Chapter 1</h1>

		<h2>Page 1</h2>
		<div>Chapter page <span class="chapter-page"></span></div>
		<div style="page-break-before: always;"></div>

		<h2>Page 2</h2>
		<div>Chapter page <span class="chapter-page"></span></div>
	</div>

	<div class="chapter" id="chapter-2">
		<h1>Chapter 2</h1>

		<h2>Page 1</h2>
		<div>Chapter page <span class="chapter-page"></span></div>
		<div style="page-break-before: always;"></div>

		<h2>Page 2</h2>
		<div>Chapter page <span class="chapter-page"></span></div>
	</div>
</body>


I tried to create a document page counter by doing this:
<style type="text/css">
	body {
		page: body;
		counter-reset: documentPage 1;
	}
	@page body {
		counter-increment: documentPage;
	}
	.chapter {
		page: chapter;
		counter-reset: page 1;
		prince-page-group: start;
	}
	.chapter-page::after {content: counter(page);}
	.document-page::after {content: counter(documentPage);}
</style>

<body>
	<div class="chapter" id="chapter-1">
		<h1>Chapter 1</h1>

		<h2>Page 1</h2>
		<div>Chapter page <span class="chapter-page"></span></div>
		<div>Document page <span class="document-page"></span></div>
		<div style="page-break-before: always;"></div>

		<h2>Page 2</h2>
		<div>Chapter page <span class="chapter-page"></span></div>
		<div>Document page <span class="document-page"></span></div>
	</div>

	<div class="chapter" id="chapter-2">
		<h1>Chapter 2</h1>

		<h2>Page 1</h2>
		<div>Chapter page <span class="chapter-page"></span></div>
		<div>Document page <span class="document-page"></span></div>
		<div style="page-break-before: always;"></div>

		<h2>Page 2</h2>
		<div>Chapter page <span class="chapter-page"></span></div>
		<div>Document page <span class="document-page"></span></div>
	</div>
</body>


But that did not work. The "documentPage" counter does not increment on every page, so it always stays at 1.

Edited by GreenRaccoon23

dauwhe
I could not get a custom page counter to work at all, even in a simpler example.

A previous post suggests this might not work.

Reading the spec, it appears that custom page counters should work :

Counters can be defined and controlled within an @page rule, and used as content in page-margin boxes. This is useful for maintaining a page count.

A counter-increment within either a page or margin context causes the counter to increment with the generation of each page box.
mikeday
Unfortunately custom page counters are not supported yet, no.

You might be able to rig up something using the prince-script() generated content but I suspect that would be rather brittle.

Supporting custom page counters mostly relies on getting the scopes right, which as I recall took numerous attempts with regular document counters. :D
GreenRaccoon23
Thank you for looking into this!

I did not find an exact solution to custom page counters, but I did find a way to get what I needed in my specific situation. I'll post it here in case it helps someone else.

In my situation, I ultimately needed the structured log of stdout to indicate which pages in the document start each chapter. I was able to do this with Javascript. After Prince renders the document, this code loops through each chapter, finds the first box in the chapter, and gets the page number of that box. This page number is the document page number of the first page in the chapter.

<style type="text/css">
	.chapter {
		page: chapter;
		counter-reset: page 1;
		prince-page-group: start;
	}
	.chapter-page::after {content: counter(page);}
</style>

<script>
	(function() {
		'use strict';

		Prince.trackBoxes = true;

		function getStartPageNumbers(items) {
			var startNumbers = [];
			for (var i = 0; i < items.length; ++i) {
				var item = items[i];
				var boxes = item.getPrinceBoxes();
				var first = boxes[0];
				var pageNum = first.pageNum;
				startNumbers.push(pageNum);
			}
			return startNumbers;
		}

		// log page numbers of the first page in each chapter
		Prince.addEventListener('complete', function() {
			var items = document.getElementsByClassName('chapter');
			var startNumbers = getStartPageNumbers(items);
			var joined = startNumbers.join(';');
			Log.data('Chapter Start Numbers', joined);
		}, false);
	}());
</script>

<body>
	<div class="chapter" id="chapter-1">
		<h1>Chapter 1</h1>

		<h2>Page 1</h2>
		<div>Chapter page <span class="chapter-page"></span></div>
		<div style="page-break-before: always;"></div>

		<h2>Page 2</h2>
		<div>Chapter page <span class="chapter-page"></span></div>
	</div>

	<div class="chapter" id="chapter-2">
		<h1>Chapter 2</h1>

		<h2>Page 1</h2>
		<div>Chapter page <span class="chapter-page"></span></div>
		<div style="page-break-before: always;"></div>

		<h2>Page 2</h2>
		<div>Chapter page <span class="chapter-page"></span></div>
	</div>
</body>