First, for testing purposes please add to the MWE:
- The option
showframe
to the geometry package.
- Put
\usepackage[pagewise]{lineno}
in the preamble.
- Insert
\linenumbers
after \maketitle
.
(After each test, compile twice to see the correct line numbers.)
Well, now analyze with calm what you asking to LaTeX in this MWE:
A not stretchable glue between paragraphs (See What is glue stretching?.) , i.e., \parskip=0pt
Some pages (4, 6, 8 ...) must have extra empty spaces of 4-8 pt, i.e., a \medskip
.
Avoid widow/orphans (mean have additional empty spaces equal to \baselineskip
in any page).
Maintain the same text length in each page.
Short answer: It makes no sense to want everything and its opposite at the same time!
I am not able to dissect this contradiction as an expert, but let's go by parts, as Jack the Ripper said:
1 + 2: Pages with only text have not any stretchable or shrinkable space. LaTeX can write in your MWE a first line at 11pt
of the top margin (test it with \the\topskip
), and next lines each 13.6pt
(\baselineskip
), so the maximum number will be \textheight
minus \topskip
, minus the depth of the last line (\pagedepth
), divided by \baselineskip
, roughly: (540.6-11-2.1)/13.6 = 38.78
. This mean a total of 39 lines, missing 10.7pt
(0.78/textheigh
) to reach the bottom margin (nearly a \baselineskip
, but insufficient for the 40th line). In contrast, the pages with \medskip
are filled thanks to the maximum of 8pt
this included rubber length \medskip
. Note that 8pt < 10.7pt
, but if you look carefully the page seem effectively full filled in spite of \parskip=0pt
. LaTeX anyway fill the entire text height with a glue beyond your allowed maximum of 8pt
, but warning of being forced to do this to avoid the worse option of fill only the 98% of the page:
Underfull \vbox (badness 3930) has occurred while \output is active [4]
In page 5 and others without the \medskip
, since the maximum allowed glue is 0pt
, a underfull \vbox
is even worse:
Underfull \vbox (badness 10000) has occurred while \output is active [5]
As a badness of 10000 mean infinitely bad. This mean that LaTeX do not have acceptable places to add some "extra glue" within the text, and therefore chooses left the ending space of 10.7pt.
1 + 3: If the last line is lost (jump to the next page) due to the high penalties for widows/orphans lines, things are still worse, since the above little glues cannot overstretch another 13.6pt. To maintain the text length, the best that could happen in this situation is that widow/orphan badness is not enough to cause any change.
2 + 3 -1: As you do not allowed separation between paragraphs setting \parskip=0pt
, this make the parskip
package useless at this respect. Just without this restrictive \parskip
setting, by default the empty final space can be distributed more or less nicely, although producing still some underfull \vbox
warnings, that can be completely cleaned using the parskip
package. The cost is sometimes ugly differences in the distance between paragraphs.
Remark: Thus, the best solution is just do not constraint \parskip
to 0pt
.
(imho, of course ...)
This spacing increase the readability of paragraph (even if there indentation), but sticking to the question, overall maintain the bottom margin consistently. My suggestion is left the dirty tricks as \enlargethispage
or \looseness
for emergencies in a final draft. Probably in many cases good microtype
settings could prevent the use of these commnads.
Beside, it could help the setting of \textheight
as \topskip
plus exact multiples of the \baselineskip` for the normal font (13.6pt in this MWE), so no glue is needed if a page is filled with the maximum number of lines.
But since the virtue is often the happy medium between two extremes, may be you want allow widow/orphan penalties, left \medskip
s untouched, insert another vertical elements and moreover, similar small skips between paragraphs. This can be obtained allowing only a little stretching/shrinking glue in \parskip, so that the sum of glues of the 3-6 paragraphs of each page are enough to fill the empty space of nearly 10pt
nicely, for example:
\setlength{\parskip}{3pt plus 3pt minus 1pt}
Just experiment with other values until find the best result for your document (or simpler and better for another reasons, left to parskip
package do the work).
If you find definitively awful even the smallest space between paragraphs, there is still one more alternative for add enough "vertical glue": Left \parskip
at 0pt or as a rubber length, but play with the \baselineskip
in the same way (it can be also a rubber length). For example, try to set something as before the first \lipsum
:
\setlength{\baselineskip}{2.85ex plus .1ex minus .05ex }
With the naked eye the small baseline changes are harder to detect than the uneven separation of paragraphs, but unfortunately note that (a) \baselineskip
cannot be adjusted in the preamble, and (b) any font size override this setting (see Is \baselineskip automatically defined?). If there are many font changes in your working document, you can consider redefine \normalsize
to set the default baseline skip. For example, adding this in the preamble:
\makeatletter
\renewcommand\normalsize{%
\@setfontsize\normalsize\@xpt{2.85ex plus .1ex minus .05ex}
\abovedisplayskip 10\p@ \@plus2\p@ \@minus5\p@
\abovedisplayshortskip \z@ \@plus3\p@
\belowdisplayshortskip 6\p@ \@plus3\p@ \@minus3\p@
\belowdisplayskip \abovedisplayskip
\let\@listi\@listI}
\makeatother
In other case, if you maintain the \parskip
,\texheight
and \baselineskip
settings of the MWE, then you should renounce to:
- window/orphan penalties and
vertical spaces other that integers of \baselineskip
. In a real document the same apply to any other object with a vertical dimension of (tabulars, floats, etc.), including their surrounding vertical spaces (certainly a hard task...). For the sake of the example only (it is a bad idea for a working document), one can redefine \medskip
:
\renewcommand\medskip{\vspace{2\baselineskip}}
% LaTeX way of say \medskipamount2\baselineskip
Then, if window/orphan lines are allowed, the redefined \medskip
not cause any difference in the bottom margin, since now take the same vertical space as two normal lines of text.
Note: I read the cited TUGboat article after first answering, so I realize that have I put the focus in allow the "TeX approach" (\parskip
glues) and the "extra leading between lines" approach (\baselineskip
glues), however, is inexcusable to forget at least a third approach of this excellent article: the traditional but still valid rewriting of the text.
Best Answer
Yes, this is possible if you are prepared to accept a certain level of false positives. Basically for both cases special penalties are used by TeX and those can be recognized in the output routine. So my code below sets the value for
\widowpenalty
to 151 and\clubpenalty
(orphans) to 152 (the LaTeX default is 150). The we use the following code:Basically we test if the
\outputpenalty
that triggered the page is either 152 or 153 or 305, ie the sum of it (which would be the case if a two line paragraph is broken). That will give us the output:and if we typeset the same document in twocolumn mode we get
You may find that other page breaks produce the same penalties (which then gives you false positives) so chosing the initial values right is essential. Of course you could use 150 and not distinguish between widow and orphan.
Final note: one should probably also add
\displaywidowpenalty
into the test (the default here is 50 in LaTeX and instead of a simple\typeout
one could think of a more elaborate output, but this is syntactic sugar.Small update
As remarked by David Carlisle elsewhere it is better not to use 151 (as I did initially for the
\clubpenalty
) as standard LaTeX uses 151 for\pagebreak[2]
so we would get some unnecessary false positives. Of course, if any of such default values are changed the above code would need to change too.Also worth noting: changing the penalties even by only such small amounts means that the break behavior of your document could get altered, i.e., it may break differently after you added that code. As this version only adds warnings it is therefore best to keep using it all the time and not make the mistake of removing it just before "final" run after having corrected all problems it reported. It may just mean that afterwards you see new breaks --- unlikely but not impossible!.
Now available as a package
A much extended version of the above code is now available on CTAN as the package
widows-and-orphans
. It automatically calculates the penalty values to make everything unique and detectible and besides widows and orphans it also detects hyphenation across column or page boundaries and math displays that got separated from the preceding text (in case that is allowed in the document).Next Tugboat will contain an article that discusses various ways to fix such issues. I will also put it up soon at https://latex-project.org/publications