Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply counter-increment on page counter when counter-reset is used #2114

Open
fsteimke opened this issue Apr 3, 2024 · 5 comments
Open

Apply counter-increment on page counter when counter-reset is used #2114

fsteimke opened this issue Apr 3, 2024 · 5 comments
Labels
bug Existing features not working as expected

Comments

@fsteimke
Copy link

fsteimke commented Apr 3, 2024

Hi,
i am not an expert for CSS, especially not for paged media. That's why i am not sure whether this is a bug, or a misunderstanding on my side.

This report is motivated by an issue with DocBook next generation stylesheets which produce books in HTML. Rendering with weasyprint gives a very good result, but page numbers in cross references and TOC are always 0 (zero), while the same file rendered with Antenna House has a correct TOC. This leads to issue #2008 for weasyprint, which says that there is no bug in weasyprint, but in the CSS.

So i tried to boil it down to very simple HTML and CSS:

  • i have a very simple HTML file with three parts: a tilepage, a TOC and the main part with two html section elements
  • i'd like to have three corresponding flows in CSS
  • the titlepage without any page number
  • the TOC with a page number in lower roman, starting at i for the first (and only) page
  • the main part with arabic page numbers, starting at 1 and a following 2

I have to use counter-reset: page two times for the toc flow and the main flow, so that they both start with i and 1.

  • when i use counter-reset at selector level, Antenna House shows the expected result. But weasyprint shows 0 for page numbers in TOC, and reset does not work (the TOC page has number II, the main pages are numbered as 3 and 4.
  • Issue I cannot get the correct TOC page number in pdf file with DocBook #2008 suggests (as far as i understand) that counter-reset:page should be placed in the @page context. When i move the counter-reset:page instruction from selector to the @page context:
    -- Antenna House: page reset does not work, pages are counted from 1 to 4, page numbers in TOC are correct;
    -- Weasyprint: all page numbers are 0 at page bottom as well as in TOC

My conclusion is: there is an issue with page numbers in combination with counter-reset in weasyprint, and placing this instruction at @page context does not help.

samples.zip

Greetings,
Frank Steimke

@liZe
Copy link
Member

liZe commented Apr 27, 2024

Hi!

Thanks for this report.

First of all, I’d like to avoid using other renderers as a source of truth. Antenna House is amazing, and it’s always useful to compare WeasyPrint with other tools, but it’s not enough to be sure that it’s the right thing to do. I’ve tried Prince (another amazing tool) and it gives results different from both WeasyPrint and Antenna House!

So, let’s focus on the specification. 😄

Page-based counters are created in pages. The text and the example show that the "page" counter is in the page context and should be controlled in the page context.

Of course, you can access these counters in the page content context. But counters are self-nested, meaning that calling counter-reset on a counter that’s already defined in a parent creates a new nested counter. For example:

<style>
  body {counter-reset: counter}
  div {counter-increment: counter}
  div::before {content: counter(counter)}
  article {counter-reset: counter}
  section {counter-increment: counter}
  section::before {content: counter(counter)}
</style>
<body>
  <div>a</div> <!-- 1 -->
  <div>b</div> <!-- 2 -->
  <div>c       <!-- 3 -->
    <article>
      <section>d</section> <!-- 1 -->
      <section>e</section> <!-- 2 -->
    </article>
  </div>
  <div>f</div> <!-- 4 -->
</body>

The counter reset in body is not the same as the one reset in article, even if they have the same name. That’s very useful, because we want the count for sections to be different from the count for divs.

So, calling counter-reset: page in the page content is just the same as this example: it creates a new "page" counter that’s available in the page content, but it shouldn’t change anything to the "page" counter that’s in the page. That’s why I disagree with what Antenna House does.

Let’s get back to your example. The main problem I see is:

@page main {
    counter-reset: page;
}

This rule resets the counter on each "main" page. So, it means that your counter won’t be incremented anymore, because it’s reset on each page.

Here’s a solution that works:

@page {
    @bottom-center {
        content: 'Page ' counter(page, arabic) ' of ' counter(pages) ' pages';
    }
}
@page main {
    counter-reset: page 1;
}
main section:first-child h1 {
    page: main;
}

It looks like we can get what you want:
test-ws.pdf

But… Using counter-reset: page 1 instead of counter-reset: page seems to be wrong, though. Having both counter-reset and counter-increment should reset and then increment the counter:

<style>
  section {counter-reset: counter; counter-increment: counter}
  section::before {content: counter(counter)}
</style>
<section></section> <!-- 1 -->

So, as far as I can tell, there’s a bug in WeasyPrint: increment should be applied on page counter even if it’s reset.

Do you agree with that?

@fsteimke
Copy link
Author

fsteimke commented May 2, 2024

I find your explanation logical and comprehensible. However, I am a beginner in the field of paged media. I cannot judge whether there are other interpretations of the specification that sound just as correct and understandable.

My main goal is to make the DocBook xslTNG stylesheets as easy to use as possible. I would therefore very much welcome it if they could be used smoothly not only with Antenna House or Prince, but also with WeasyPrint. My impression is that this can work well, but so far there is still the CSS problem with wrong page numbers. (And there is one more software that i'd like to include in the tests: Its Oxygen Chemistry which converts (HTML+CSS) to FOP, it ships with the Oxygen Editor product family).

I have to check if I can integrate your solution into the CSS for xslTNG. I will try, but since I am not an expert, I may need more help.

For now, thank you very much for the detailed analysis and explanation. I will definitely get back to you when I have something new to report from the implementation for the CSS in xslTNG.

In the meantime, can you possibly correct the error with counter-reset()?

Greetings, Frank

Translated with DeepL.com (free version)

@liZe
Copy link
Member

liZe commented May 2, 2024

In the meantime, can you possibly correct the error with counter-reset()?

OK, let’s focus on this.

@liZe liZe changed the title All page numbers in TOC are zero when i reset page counter Apply counter-increment on page counter when counter-reset is used May 2, 2024
@liZe liZe added the bug Existing features not working as expected label May 2, 2024
@fsteimke
Copy link
Author

fsteimke commented May 3, 2024

I am sorry, but I realize that despite your explanations, I am not able to develop the correct solutions for the example.

I do understand that i have to avoid unintentionally creating a new counter called page by a counter-reset in the wrong place. I think that i also do understand that

@page main {
    counter-reset: page;
}

is a problem, because i resets a counter called page on every page called main. But i do not understand, why

@page main {
    counter-reset: page 1;
}

is part of a solution that works? It seems to be exactly the same, the only difference (the initial value) should be irrelevant. I am sure i missed the point where the real difference is, sorry for that.

Maybe you can provide the full code of the correct CSS file which, when applied to the HTML in the sample, will produce the PDF file that you already presented? This would give me a chance to study it in detail.

Thanks in advance,
Frank Steimke

@liZe
Copy link
Member

liZe commented May 3, 2024

I am sure i missed the point where the real difference is, sorry for that.

The difference is:

main section:first-child h1 {
    page: main;
}

The main page is only the first one of the main content. Of course, you can use a better name :).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Existing features not working as expected
Projects
None yet
Development

No branches or pull requests

2 participants