Exercise group: add page break penalty?

21 views
Skip to first unread message

Sean Fitzpatrick

unread,
Jun 3, 2026, 1:59:23 PMJun 3
to prete...@googlegroups.com
One thing I am noticing fairly regularly in my PDF build is that a new
exercise group will start at the bottom of a page.

So we will get, for example, something like the following as the last
part of a page:


Exercise Group. A graph of a function f(x) is given. Use the graph to
estimate the value of the definite integral.


All the exercises for this group will then be on the next page. It seems
like it would be better to break the page before the Exercise Group
heading, so that the introduction and exercises appear on the same page.

Is there a way that we could write in a pagebreak hint for this
situation? I can manually add page breaks, of course, but in theory we
want to avoid this.

Sean Fitzpatrick

unread,
Jun 3, 2026, 2:39:33 PMJun 3
to prete...@googlegroups.com
I should add that I've tried using the pagebreak 'insertions' in the
publication file, but it doesn't work for exercise groups. (Or anywhere
in divisional exercises, unless I do something hacky, like put an empty
#p at the end of the statement of the exercise prior to the exercise
group I want the pagebreak for, and then insert the pagebreak on that
empty paragraph.)

Rob Beezer

unread,
Jun 3, 2026, 3:01:22 PMJun 3
to prete...@googlegroups.com
Dear Sean,

Yes, let's try to fix this up.

While you have lots of (problemm) instances, do you mind doing a bit of
experimenting? Insert some LaTeX hints into your raw LaTeX by hand, and see
what works best? Note that pretext/pretext will build a whole LaTeX setup with
all the images, etc, just ready to compile.

My first idea would be to try to "bind" the instructions with the first row full
of #exercise. Maybe they both land at the end of a page, maybe they both
migrate to the next page. Maybe that minimizes the dead whitespace that can
result. I suspect a \par is coming from whatever precedes the #exercisegroup.
We don't want to adjust fifty templates on the off-chance an #exercisegroup
follows them. Better to get into the guts of the #exercisegroup template. I
think. This is all speculation, but perhaps that will help guide your
experiments. I could also turn my assistant loose on this one.

The preserved page-breaks in the publisher file is really meant for "bigger"
objects, and I think the feature needs to be enabled for each one. That said,
we do have page-break hints available for #md, so that could also be a model for
rows of an #exercisegroup.

Rob

Sean Fitzpatrick

unread,
Jun 3, 2026, 5:19:21 PMJun 3
to prete...@googlegroups.com
It seems that this is most likely to be triggered when an exercise group
has columns.

Quick experiments:

an exercise group begins with

\par\medskip\noindent
\par\medskip\noindent%
\textbf{Exercise Group.}\space\space\hypertarget{...}{}%
Whatever text was written in the introduction

Putting a \pagebreak[3] just before does nothing. (\pagebreak[4] works
everywhere and is a bad idea)

Putting a \nopagebreak[4] just after noes nothing. if I get rid of
columns, the \nopagebreak suffices to keep the text of the next exercise
on the same page.

(OK, but what I wanted was to push the exercise group introduction to
the *next* page!)

I tried a few other penalties, but didn't have much success.

I don't want to rewrite the whole template for this, but what I think
would be sufficient is:

a) put an xml:id on the exercise group that's causing trouble

b) put that xml:id in the <insertions pagebreaks=""/> and have it work


Right now, putting those xml:ids in has no effect. Perhaps not
surprising, since the template for exercises is very complicated.

I think the pagebreak insertions method actually uses \newpage and not
\pagebreak. Related to that:

Here is the initial .tex, with two locations that I've marked as (A), (B):

\par\medskip\noindent(A)
\par\medskip\noindent%
(B)
\textbf{Exercise Group.}\space\space\hypertarget{...}{}%
Whatever text was written in the introduction

Inserting either \pagebreak or \newpage at (A) does what we want.

Inserting \pagebreak at (B) does nothing!

Inserting \newpage at (B) breaks the page, but the lack of a \noindent
is a problem: the Exercise Group heading gets indented.

TL;DR: I need to look at the templates for the 'insertions' mechanism
(and maybe the exercise group template) to figure out why a \newpage
isn't written when you include an xml:id from an exercise group.

Then I need to make sure it goes in the right place.

Sean Fitzpatrick

unread,
Jun 4, 2026, 12:03:22 PMJun 4
to prete...@googlegroups.com
I have a proposed solution that I think has minimal impact on the
exercisegroup template.

I'm looking at the exercisegroup template in pretext-latex-common.xsl,
beginning at line 6152 in the current version.

For whatever reason, Alex's newpage template (for publisher-inserted
page breaks) doesn't catch exercise groups.

The exercisegroup template begins with some logic to set the number of
columns. Then we have the following lines to write the title and
introduction:

    <!-- build it -->
<xsl:text>\par\medskip\noindent%&#xa;</xsl:text>
    <xsl:text>\textbf{</xsl:text>
    <!-- title may be default title -->
    <xsl:apply-templates select="." mode="title-full" />
    <xsl:text>}\space\space</xsl:text>
    <xsl:apply-templates select="." mode="optional-label"/>
    <xsl:text>%&#xa;</xsl:text>
    <xsl:apply-templates select="introduction" />


Immediately below the <!-- build it --> comment, I inserted:

    <xsl:if test="@xml:id = str:tokenize($latex-pagebreaks-string)">
        <xsl:text>\newpage&#xa;</xsl:text>
    </xsl:if>

if the xml:id of the exercise group is listed in teh publisher file for
a pagebreak insertion, this adds the needed \newpage at the right place.

Otherwise, it does nothing.

This will do what I need. If it seems otherwise harmless, I'll open a
pull request.

Alex Jordan

unread,
Jun 4, 2026, 12:40:04 PMJun 4
to prete...@googlegroups.com
About publisher pagebreaks, we didn't do that for numbered or block level things. On the one hand, it should be harmless if you wanted to extend "exercisegroup" into the list of things that applies to. On the other hand, this seems like something that should be coming out better automatically. So adding exercisegroup to the list might be putting a band-aid over something instead of curing the real issue. Your call.





--
You received this message because you are subscribed to the Google Groups "PreTeXt development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pretext-dev...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/pretext-dev/27f7915e-34c4-4ae3-ad24-ebfec6bc681d%40gmail.com.

Sean Fitzpatrick

unread,
Jun 4, 2026, 12:46:33 PMJun 4
to prete...@googlegroups.com

I am open to better solutions!

I'm basing this on my understanding of what I saw in the XSL, which is (shall we say) limited.

Publisher pagebreaks seem to be working fine if I use the xml:id of a theorem or definition (which I think is a numbered or block level thing?)

I agree that it would be great if the exercisegroup title and introduction did not get orphaned (or is that widowed?). I tried a few things yesterday, but all of them either didn't break the page when I wanted it to, or did break the page before every exercise group!

Alex Jordan

unread,
Jun 4, 2026, 12:49:47 PMJun 4
to prete...@googlegroups.com
Yeah, that's right. I guess we did do numbered block things. So maybe exercisegroup is an unintentional omission.

Alex Jordan

unread,
Jun 4, 2026, 12:55:55 PMJun 4
to prete...@googlegroups.com
I think if you put:

<xsl:apply-templates select="." mode="newpage"/>

somewhere early in the template for exercisegroup in pretext-latex-common.xsl, then you can start doing this with exercisegroups.

Sean Fitzpatrick

unread,
Jun 4, 2026, 12:58:11 PMJun 4
to prete...@googlegroups.com

I will try that and see if it works the same as what I put.

Getting page breaks right for exercise groups without publisher page breaks is a bit beyond my level of TeXpertise, so I am willing to settle for putting in the page breaks when they're needed.

Sean Fitzpatrick

unread,
Jun 4, 2026, 1:02:58 PMJun 4
to prete...@googlegroups.com

I can confirm that this works the same as my earlier attempt (and is surely more robust).

On 2026-06-04 10:55, Alex Jordan wrote:

Alex Jordan

unread,
Jun 4, 2026, 1:43:30 PMJun 4
to prete...@googlegroups.com
If you open a PR, I will sign off on it. Just to check that there is not something subtle about where you inserted that line.

Sean Fitzpatrick

unread,
Jun 4, 2026, 1:49:23 PMJun 4
to PreTeXt development
The template for exercise group currently leads with a \par\medskip\noindent

The page break template has to go *before* this line, or you get an unwanted integration. 

The preceding exercise or exercise group also ends with \par\medskip\noindent%
so my current placement puts the \newpage between these two lines. I think that's the right place. 

I'm about to go through APEX once more (to see if Greg will sign off on the PDF).

That gives me a few hundred exercise groups to check for weirdness.

Alex Jordan

unread,
Jun 4, 2026, 1:57:00 PMJun 4
to prete...@googlegroups.com
OK, and please report any weirdness about this kind of thing, even if it's not related to the change you are making now. I have a branch of pretext I use for orcca with a dozen or more tweaks to stamp out maybe 90% of the need to use publisher specified page breaks. And maybe some of them should be discussed publicly, tested out by you with APEX, and then contributed.

Sean Fitzpatrick

unread,
Jun 4, 2026, 5:24:16 PMJun 4
to prete...@googlegroups.com

PR opened.

No issues from this code change.

One bit of line breaking weirdness: a theorem that ended with a display equation, at the end of a page.

There's some vertical padding after display math. This cause the tcolorbox for the theorem to spill onto the next page, but it had no content! There was just a green blob at the top of the page.

But that could be user error, since I have custom tcolorbox settings for theorem and other blocks.

Rob Beezer

unread,
Jun 6, 2026, 3:03:50 PMJun 6
to prete...@googlegroups.com
PR at https://github.com/PreTeXtBook/pretext/pull/2890 has been merged, so this
will be available in new releases.

I asked my assistant to do a sweep for similar gaps in coverage, and
#subexercises was the only new structure to add. And so it has been.

https://github.com/PreTeXtBook/pretext/pull/2896

Rob
>>>> dev+uns...@googlegroups.com <mailto:pretext-
>>>> dev%2Bunsu...@googlegroups.com>.
>>>> To view this discussion visit https://
>>>> groups.google.com/d/msgid/pretext-
>>>> dev/27f7915e-34c4-4ae3-ad24-ebfec6bc681d%40gmail.com.
>>>>
>>>> --
>>>> You received this message because you are subscribed to
>>>> the Google Groups "PreTeXt development" group.
>>>> To unsubscribe from this group and stop receiving emails
>>>> from it, send an email to pretext-
>>>> dev+uns...@googlegroups.com.
>>>> To view this discussion visit https://groups.google.com/
>>>> d/msgid/pretext-dev/CA%2BR-
>>>> jrd%2BBqZWOEWpHZQPmBNPALaq%3Dy6AaSpc4DVYXE7ZaNU4_g%40mail.gmail.com <https://groups.google.com/d/msgid/pretext-dev/CA%2BR-jrd%2BBqZWOEWpHZQPmBNPALaq%3Dy6AaSpc4DVYXE7ZaNU4_g%40mail.gmail.com?utm_medium=email&utm_source=footer>.
>>> --
>>> You received this message because you are subscribed to
>>> the Google Groups "PreTeXt development" group.
>>> To unsubscribe from this group and stop receiving emails
>>> from it, send an email to pretext-
>>> dev+uns...@googlegroups.com.
>>> To view this discussion visit https://groups.google.com/
>>> d/msgid/pretext-
>>> dev/2c2097e7-50b4-42aa-906a-84954eaec1e6%40gmail.com
>>> <https://groups.google.com/d/msgid/pretext-
>>> dev/2c2097e7-50b4-42aa-906a-84954eaec1e6%40gmail.com?
>>> utm_medium=email&utm_source=footer>.
>>>
>>> --
>>> You received this message because you are subscribed to the
>>> Google Groups "PreTeXt development" group.
>>> To unsubscribe from this group and stop receiving emails from it,
>>> send an email to pretext-dev...@googlegroups.com.
>>> To view this discussion visit https://groups.google.com/d/msgid/
>>> pretext-dev/CA%2BR-jreRD0q7A4JFdMPn9vibqTWCq-
>>> F8XWW8rZgOhLvr%2BpVpHA%40mail.gmail.com <https://
>>> groups.google.com/d/msgid/pretext-dev/CA%2BR-
>>> jreRD0q7A4JFdMPn9vibqTWCq-
>>> F8XWW8rZgOhLvr%2BpVpHA%40mail.gmail.com?
>>> utm_medium=email&utm_source=footer>.
>> --
>> You received this message because you are subscribed to the Google
>> Groups "PreTeXt development" group.
>> To unsubscribe from this group and stop receiving emails from it,
>> send an email to pretext-dev...@googlegroups.com.
>> To view this discussion visit https://groups.google.com/d/msgid/
>> pretext-dev/e9212982-5c11-435b-ae4f-789d2e164e7b%40gmail.com
>> <https://groups.google.com/d/msgid/pretext-dev/e9212982-5c11-435b-
>> ae4f-789d2e164e7b%40gmail.com?utm_medium=email&utm_source=footer>.
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "PreTeXt development" group.
>> To unsubscribe from this group and stop receiving emails from it, send
>> an email to pretext-dev...@googlegroups.com.
>> To view this discussion visit https://groups.google.com/d/msgid/
>> pretext-dev/CA%2BR-jre2RjgDEumK7m-
>> YF30kOpcA2ptTLCk7fx1POxeQw8Zy%3Dw%40mail.gmail.com <https://
>> groups.google.com/d/msgid/pretext-dev/CA%2BR-jre2RjgDEumK7m-
>> YF30kOpcA2ptTLCk7fx1POxeQw8Zy%3Dw%40mail.gmail.com?
>> utm_medium=email&utm_source=footer>.
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "PreTeXt development" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to pretext-dev...@googlegroups.com.
>> To view this discussion visit https://groups.google.com/d/msgid/pretext-
>> dev/CAH%2BNcPZCNL-5YQOs58OPxjZDjyO56YNFgegwMR4DaBgoWW0CZg%40mail.gmail.com
>> <https://groups.google.com/d/msgid/pretext-dev/
>> CAH%2BNcPZCNL-5YQOs58OPxjZDjyO56YNFgegwMR4DaBgoWW0CZg%40mail.gmail.com?
>> utm_medium=email&utm_source=footer>.
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "PreTeXt development" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to pretext-dev...@googlegroups.com.
>> To view this discussion visit https://groups.google.com/d/msgid/pretext-dev/
>> CA%2BR-jrdzp6gWpiGjJvzcggTT2n0i9OQwYynvxszG2o7ng0oXZA%40mail.gmail.com
>> <https://groups.google.com/d/msgid/pretext-dev/CA%2BR-
>> jrdzp6gWpiGjJvzcggTT2n0i9OQwYynvxszG2o7ng0oXZA%40mail.gmail.com?
>> utm_medium=email&utm_source=footer>.
>
> --
> You received this message because you are subscribed to the Google Groups
> "PreTeXt development" group.
> To unsubscribe from this group and stop receiving emails from it, send an email
> to pretext-dev...@googlegroups.com <mailto:pretext-
> dev+uns...@googlegroups.com>.
> To view this discussion visit https://groups.google.com/d/msgid/pretext-
> dev/14912197-f4d9-4fdd-ae77-ad6234261357%40gmail.com <https://groups.google.com/
> d/msgid/pretext-dev/14912197-f4d9-4fdd-ae77-ad6234261357%40gmail.com?
> utm_medium=email&utm_source=footer>.

Sean Fitzpatrick

unread,
Jun 6, 2026, 4:03:06 PMJun 6
to PreTeXt development
Thanks! APEX PDF is starting to look more than respectable

Rob Beezer

unread,
Jun 6, 2026, 4:29:18 PMJun 6
to prete...@googlegroups.com
> look more than respectable

That's a high bar!

Sean Fitzpatrick

unread,
Jun 8, 2026, 2:51:49 PM (12 days ago) Jun 8
to prete...@googlegroups.com
I think I spotted one other instance that isn't implemented. (Or if it
is, I'm using it wrong.)

There is pagebreak support for exercise/solution, but I don't think
there is pagebreak support for example/solution

This comes up for me in one scenario, which is when I have
example/solution/p/ol

The "Solution" heading can end up alone at the bottom of the page. Not
the end of the world.

But I was hoping I could put an xml:id on the solution, and then include
that id in the publisher file, and this doesn't seem to accomplish anything.

Sean Fitzpatrick

unread,
Jun 11, 2026, 11:38:15 AM (9 days ago) Jun 11
to prete...@googlegroups.com
My earlier observation was mistaken. There is a single solution template
that is used for both exercise and example. It has the newpage template
in place.

However, if I put an xml:id on a solution, it doesn't survive
processing. (At least, it doesn't show up anywhere in the .tex file.)

So my guess is that the newpage template fails in this case because the
xml:id listed in in the publication file ends up not pointing to
anything in the assembled source.
Reply all
Reply to author
Forward
0 new messages