% This file is part of the CTAN package named plain-widow.
% 
%   pxwsingle.tex: change \plainoutput to \PXsinglepage
%                  that writes a report about problematic lines
%                  and prevents widow lines in a text by changing \vsize
%   Version 1.0, 13.05.2025
%
%   Copyright (C) 2025  Udo Wermuth (author)
%
%   This program is free software: you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation, either version 3 of the License, or
%   (at your option) any later version.
%
%   This program is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You should have received a copy of the GNU General Public License
%   along with this program.  If not, see <http://www.gnu.org/licenses/>.
%
\input pxwreport.tex
\holdinginserts=1 % change its default value
\newbox\PrevPageBotMark % box to store \botmark
\def\SaveCurrentBotMark{% fill \PrevPageBotMark
 \global\setbox\PrevPageBotMark % must be global
  =\vbox{Restore\mark{\botmark}\vfil}}
\SaveCurrentBotMark % initialize the box
\def\RestoreBotMark{-"C0DA }% unique < -10000
\def\footlinedist{30pt }%plain TeX's value: 24pt
\def\makefootline{\baselineskip=\footlinedist
 \lineskiplimit=0pt\line{\the\footline}}
\begingroup \dimen255=\footlinedist
 \gdef\PXnormaldist{\gdef\footlinedist{30 pt}}
 \advance\dimen255 by +1\baselineskip
 \xdef\PXplusdist{\noexpand\gdef\noexpand
  \footlinedist{\the\dimen255 }}
 \advance\dimen255 by -2\baselineskip
 \xdef\PXminusdist{\noexpand\gdef\noexpand
  \footlinedist{\the\dimen255 }}\endgroup
\def\PXincVsize{% increase \vsize by one line
 \global\advance\vsize by +1\baselineskip
 \PXminusdist\wlog{SINGLE: \vsize + 1 line}}
\def\PXdecVsize{% decrease \vsize by one line
 \global\advance\vsize by -1\baselineskip
 \PXplusdist\wlog{SINGLE: \vsize - 1 line}}
\def\PXresetVsize{% reset \vsize to former value
 \ifdim\vsize=\PXsaveVsize \else \PXnormaldist
  \global\vsize=\PXsaveVsize \fi}
\def\PXstorevsize{\edef\PXsaveVsize{\the\vsize}}
\PXstorevsize % call this if \vsize is changed
\newif\ifPXshowoutputroutine % true: show method
\def\PXlog#1{% #1: string; flag-protected \wlog
 \ifPXshowoutputroutine\wlog{#1}\fi}
\def\PXsinglepage{% prevent club and widow lines
 \ifnum\outputpenalty=\RestoreBotMark
  \setbox0=\vbox{\unvbox255 }%   ignore contents
 \else\ifnum\outputpenalty=\PXpenW
  \PXincVsize \unvbox255 %    keep \penalty10000
 \else\ifnum\outputpenalty=\PXpenBW
  \PXincVsize \unvbox255
 \else\ifnum\outputpenalty=\PXpenCW
  \PXincVsize \unvbox255
 \else\ifnum\outputpenalty=\PXpenBCW
  \PXincVsize \unvbox255
 \else\ifnum\outputpenalty=\PXpenC
  \PXdecVsize \unvbox255
 \else\ifnum\outputpenalty=\PXpenCD
  \PXdecVsize \unvbox255
 \else\ifnum\outputpenalty=\PXpenBC
  \PXdecVsize \unvbox255
 \else\ifnum\outputpenalty=\PXpenBCD
  \PXdecVsize \unvbox255
 \else\ifnum\holdinginserts=1 % switch its value
  \global\holdinginserts=0
  \unvbox\PrevPageBotMark  % restore \botmark to
  \penalty\RestoreBotMark % get a valid \topmark
  \unvbox255 %          next, reprocess material
  \ifnum\outputpenalty<10000 % including penalty
   \penalty\outputpenalty \fi% keep \TeX's 10000
 \else \SaveCurrentBotMark   % for next \topmark
  \PXlog{OUTPUT: single }\PXoutput \PXresetVsize
  \global\holdinginserts=1 \PXpostsingle
 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
\output={\PXsinglepage}
\let\PXpostsingle=\relax
\def\startwithReport{\holdinginserts=0
 \output={\PXoutput}}
\def\fromSingletoReport{%
 \def\PXpostsingle{\global\holdinginserts=0
  \global\output={\PXoutput}}}
\def\fromReporttoSingle{%
 \SaveCurrentBotMark \global\holdinginserts=1
 \global\let\PXpostoutput=\relax
 \global\let\PXpostsingle=\relax
 \global\output={\PXsinglepage}}
