Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

There have been several questions about how to avoid widows and orphans, so let me first state that that is not the question here. I know I can try and tweak the settings but that it's still possible to end up with widows and orphans.

What I do want to ask is whether there is some easy way (package) to get a list of all the widows and orphans that are in the document. Written to a separate file or just outputted when the processing of the file is done.

share|improve this question

1 Answer 1

up vote 15 down vote accepted

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:

\documentclass %[twocolumn]
    {article}

\clubpenalty=152
\widowpenalty=151

% we want to know if we are on first or second column in a 2 column document
\makeatletter
  \def\oncol{\if@twocolumn \space \if@firstcolumn  (first \else (second \fi column)\fi}
\makeatletter

% check if the output penalty was due to orphan or widow or both
\def\testforwidowsandorphans{%
   \ifnum\outputpenalty=151
        \typeout{*** Widow on page  \thepage \oncol}%
  \else
       \ifnum\outputpenalty=152
          \typeout{*** Orphan on page \thepage \oncol}%
      \else
         \ifnum\outputpenalty=303
            \typeout{*** Orphan and Widow on page \thepage \oncol}%
        \fi
      \fi
 \fi
}

% execute this code at the very beginning of the OR
\toks0=\output
\output\expandafter{\expandafter\testforwidowsandorphans
                                   \the\toks0}


\newcommand\stupidpara{First line\\second line\\and final line\par}
\newcommand\verystupidpara{First line\\and final one\par}

\setlength\textheight{5\baselineskip}

\begin{document}
  \stupidpara\stupidpara\stupidpara\stupidpara
   \verystupidpara\verystupidpara\verystupidpara\verystupidpara
\end{document}

Basically we test if the \outputpenaltythat triggered the page is either 151 or 152 or 303, ie the sum of it (which would be the case if a two line paragraph is broken). That will give us the output:

*** Widow on page 1
[1]
*** Orphan on page 2
[2]
*** Orphan and Widow on page 3

and if we typeset the same document in twocolumn mode we get

*** Widow on page 1 (first column)
*** Orphan on page 1 (second column)
[1]
*** Orphan and Widow on page 2 (first column)

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 distingusih 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 \typeoutone could think of a more elaborate output, but this is syntactic sugar.

share|improve this answer
2  
Nice. Can we have a package, please? –  Martin Schröder Feb 28 '12 at 23:12
    
@Martin sure but probaby not by me :-) –  Frank Mittelbach Feb 29 '12 at 17:37
    
Very nice idd. False positives aren't a problem. Thanks very much. –  nvcleemp Mar 1 '12 at 6:47

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.