Why do I need state for some (here some specific) show rules?

The problem in option 1 is that the layout doesn’t converge. Typst makes multiple layout iterations until the layout “converges”, meaning until it doesn’t change anymore.

For your example: In the first run, the y position will be zero because Typst doesn’t know yet where the heading will be placed, so no page break will be inserted. So after the first run the headings are placed “as usual”. Then it goes into the second run. Now the position will give you the “usual position”. So it detects the bad headings and inserts the appropriate page breaks. The result of this is basically the document that you want. However, the layout looks different from the previous iteration (i.e. didn’t converge yet), so we go into a third run. Now for third run, it return as positions the new positions (how you want them to be). That means no heading will be detected as a bad heading, and hence no page breaks will be inserted, or in other words, the page breaks will be removed again. So what gets compiled is the document from the start! In this fashion it will switch infinitely back and forth between the “usual” document and the document that you want. Hence a compiler error that the layout doesn’t converge.

In your second option you managed (probably more by luck if I may say so) to bypass this problem. You can go through the different iterations by hand and check that doesn’t lead to the infinite back-and-forth. In fact, if I’m not mistaken, that’s because of a funny “back-and-forth” between the state and the iterations. The state is basically always the opposite of what you want it to be. Whatever.

Let me mention another point with which you have to be careful when implementing this. If your implementation makes the fix say at the second layout iteration, that could be too early. Because the content could still change (because of many other context calls). That means it could still happen that an already-fixed heading will be turned bad again because say in the third iteration suddenly a lot of text appears before the heading. This makes implementing the behavior you want a little challenging, good luck. :smiley:

3 Likes