WeasyPrint icon indicating copy to clipboard operation
WeasyPrint copied to clipboard

Preserve page groups during layout repagination

Open YakBizzarro opened this issue 5 months ago • 6 comments

The page groups are not preserved during layout repagination. If a counter is reset in a page group with nth, the reset might happen multiple times.

Fix #2485.

YakBizzarro avatar Jun 30 '25 14:06 YakBizzarro

Hi!

Thanks a lot for the bug report, and for your work on this pull request.

I think that the problem is a bit more complex: we actually have to keep the state of page groups for all pages, as we do for counters (in page_maker’s page_state). Here’s an example that doesn’t work with your fix:

<!DOCTYPE html>
<html>
  <head>
    <style>
      div { page: group }
      h1 { break-before: page }
      p.counter::after { content: counter(pages) }
      @page :nth(1 of group) { background-color: green }
    </style>
  </head>
  <body>
    INTRO PAGE
    <div>
      <h1>Title</h1>
      <p>content</p>
      <h1>Title</h1>
      <p class="counter">content</p>
    </div>
    <div>
      <h1>Title</h1>
      <p>content</p>
      <h1>Title</h1>
      <p class="counter">content</p>
    </div>
  </body>
</html>

Would you be interested in updating your pull request? If you are, don’t hesitate to ask for hints!

(To be honest, the code that handles the page status is not in good shape and would definitely benefit from a large lifting. The data structure is a mess, but let’s keep this for later…)

liZe avatar Jul 06 '25 12:07 liZe

sure, if you have more hints for me it would be great, thanks!

YakBizzarro avatar Jul 24 '25 11:07 YakBizzarro

@liZe any suggestion how to proceed? :) thanks!

YakBizzarro avatar Aug 18 '25 09:08 YakBizzarro

any suggestion how to proceed? :) thanks!

Sorry for the delay, it’s a bit hard to find time for all the tickets during the holidays. I’ll answer soon! :pray:

liZe avatar Aug 18 '25 15:08 liZe

The bug comes from the fact that when a page is repaginated, we need to remember the status of the page groups at the moment the page was first paginated. The same is already done for counters, for example.

To do this for counters, we store information in page_state:

https://github.com/Kozea/WeasyPrint/blob/e1649e85bfd5fb3eb4589edd02438ef45998102d/weasyprint/layout/init.py#L59-L64

Adding page_groups as a fourth element of page_state should save it for each page and give the possibility to reuse it for repagination. There’s then no need to give page_groups to make_all_pages and remake_page, as we’ll find it as page_state[3]:

https://github.com/Kozea/WeasyPrint/blob/e1649e85bfd5fb3eb4589edd02438ef45998102d/weasyprint/layout/page.py#L906

It should then work as expected! :crossed_fingers:

liZe avatar Aug 25 '25 08:08 liZe

hi @liZe , sorry for the long delay. I reworked the patch according to your suggestion, many thanks for the guidance! I added a new test case based on your suggestion. I hope that fixes it! :)

YakBizzarro avatar Nov 27 '25 10:11 YakBizzarro