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

LaTeX: make it less likely to page break following solution-like heading #2199

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Alex-Jordan
Copy link
Contributor

In LaTeX/PDF. This is a proposal for your consideration.

Sometimes the first piece of content following a solution-like heading is something that naturally uses a \par before getting started. Examples of this would be like when a solution immediately goes into a list or a tabular. When that happens, the heading (like "Solution") could be at the bottom of a page, and then there is a page break before you get to the first piece of content for that solution. Here is a screenshot where "Solution" has been renamed to "Explanation", and you can see such a header at the bottom.

Screenshot 2024-07-07 at 4 16 37 PM

This PR proposes increasing the page break penalty in as minimal a way I could think of, so that it's less likely to have a page break in between the solution-like heading and the first piece of content. After this PR, it looks like:

Screenshot 2024-07-07 at 4 04 03 PM

The verso page now looks like:

Screenshot 2024-07-07 at 4 20 39 PM

@rbeezer
Copy link
Collaborator

rbeezer commented Jul 8, 2024

Like the sentiment here. I'd say 'hint' and 'answer' are equally deserving. Maybe this does that?

I do not like anything using 'makeatletter' even in preamble. But certainly not hundreds of times in source. Aren't there macros that have like a 1,2,3,4 argument for aggresiveness?

Many things (like comments) contribute to 'position()'. Best avoided. Or build a list of desired elements, and use a 'for-each' to change context.

@Alex-Jordan
Copy link
Contributor Author

Like the sentiment here. I'd say 'hint' and 'answer' are equally deserving. Maybe this does that?

Yes, "solution-like" encompasses hint and answer.

I do not like anything using 'makeatletter' even in preamble. But certainly not hundreds of times in source. Aren't there macros that have like a 1,2,3,4 argument for aggresiveness?

I'll look into this.

Many things (like comments) contribute to 'position()'. Best avoided. Or build a list of desired elements, and use a 'for-each' to change context.

If the select is on *[position() ...], is it not the case that it is looking at the position among element nodes? That is, first it gathers a nodeset of *, then it established position among those nodes?

@rbeezer
Copy link
Collaborator

rbeezer commented Jul 11, 2024

Can we bury \nopagebreak somewhere in a macro or tcolorbox or similar, were it won't be seen all over the place? No matter what, just as a matter of course, so we don't need to see if there is a special situation?

http://www.emerson.emory.edu/services/latex/latex_110.html

@sean-fitzpatrick
Copy link
Contributor

I don't have an opinion on how this is implemented, but I'd like to point out another case that should be included here:

If an exercisegroup occurs at the bottom of a page, and the introduction is sufficiently short, one can end up with the last line on a page being something like:

Exercise group. Compute the derivative of the following functions.

And then the exercises follow on the next page. That heading and instruction should move over to the next page with the exercises it refers to.

@rbeezer
Copy link
Collaborator

rbeezer commented Jul 18, 2024

@sean-fitzpatrick - can you experiment with manually inserting a \nopagebreak[4] at various places (by hand into a *.tex file we produce)? Then in some part of the environment definition for an exercisegroup?

@Alex-Jordan
Copy link
Contributor Author

Things I learned earlier.

We have whatever commands we use to print a title, and then whatever environment we open for whatever comes next. And you might think that putting a \nopagebreak in between them would help to prevent these unwanted page breaks. But it turns out that the opening lines of internal code for the environment we are entering typically has multiple breakpoints (opportunities for LaTeX to make a page break). So placing that \nopagebreak will not help typically, because LaTeX will use one of these "hidden" breakpoints.

This is what led me to the basic idea here, to temporarily change the penalty for a page break. And then that applies to all the opportunities for a page break, including the "hidden" ones.

@sean-fitzpatrick
Copy link
Contributor

@Alex-Jordan it sounds like you already know what will be the result of the experiment suggested by @rbeezer ?

I'm also wondering how hard it would be to adjust the pagebreak penalty for environments like theorem, definition, etc.

Example use case: a Definition takes 12 lines of text, and the pagebreak occurs on line 11, stranding the last line of the definition on the next page. I don't think this should happen. I can fix it using an \enlargethispage command before the start of the definition but this seems less than ideal.

@Alex-Jordan
Copy link
Contributor Author

Science experiments should be reproducible! :) I don't mean to discourage you trying, and maybe things are different with an exercisegroup than with a solution like I originally investigated.

@sean-fitzpatrick
Copy link
Contributor

I'll give it a try. Since he recently tackled some other LaTeX subtleties, I wonder if @jjrsylvestre has any insight on this?

@sean-fitzpatrick
Copy link
Contributor

Changing the first line to

\textbf{Exercise Group.}\space\space\hypertarget{exset-deriv-inverse-tangent}{}\nopagebreak[4]%

did the trick: the exercise group title and introduction move to the next page.

@sean-fitzpatrick
Copy link
Contributor

sean-fitzpatrick commented Jul 18, 2024

If we wanted this change universally, I think changing line 5594 of pretext-latex.xsl from <xsl:text>%&#xa;</xsl:text> to <xsl:text>\nopagebreak[4]%&#xa;</xsl:text> would get the job done.

@sean-fitzpatrick
Copy link
Contributor

I can confirm that although \nopagebreak works fine for exercisegroup, it does not work for solution or solution-like.
So a different solution is needed there. I tried a few variations, and none of them were successful.

(Of course I can put a pagebreak before the solution title, but that can't be automated.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants