%  F W L W . S T Y  ( First Word, Last Word )
%
%  Donald Arseneau  (May 1, 1993)
%
%  Modifications to LaTeX output mechanism to determine the first and
%  last words on the current page, plus the first word on the *next*
%  page.  These can be used in head-lines or foot-lines.
%
%  Such labelling does not make sense when \chapter generates a page
%  break.  You may need to modify the \chapter macro to give useful
%  behavior.  Presently, the last page before a \chapter (or any
%  \clearpage) gets a blank "next word", and the first page of the
%  chapter gets a blank "first word".
%
%  The words are available in the box registers:
%     \LW@firstWbox     -  first word on this page
%     \LW@nextfirstWbox -  first word on next page
%     \LW@lastWbox      -  last word on this page
%  Use them in your head-lines like: \copy\LW@lastWbox.
%
%  Note that "words" may be things like:
%    - two~words
%    - [ ]Word  ( [ ] represents a parindent box)
%    - a whole displayed equation
%    - anomalously blank, if there are \writes or other things.
%    - par-  or   -tial.
%  The "first word" should be printed flush right because of the possible
%  parindent box attached to it.

\newbox\LW@firstWbox     \global\setbox\LW@firstWbox\hbox{}
\newbox\LW@nextfirstWbox \global\setbox\LW@nextfirstWbox\hbox{}
\newbox\LW@lastWbox      \global\setbox\LW@lastWbox\hbox{}
\newbox\LW@box           \global\setbox\LW@box\hbox{}
\newbox\LW@saved

%  Shell around old output routine.  Gets first word from next page by
%  letting TeX continue with \vsize=0 to get a look at the next line.
%  Values of \outputpenalty for \specialoutput ( -10001 to -19999 ) are
%  simply run through the output routine.
%  \supereject and \clearpage give a blank "next word"
%  When called after making a stub-page the stub is returned to the vertical
%  list, the previous page is restored and shipped out normally, but
%  knowing what the next word will be.

\edef\norm@L@output{\the\output
  \global\setbox\LW@firstWbox\box\LW@nextfirstWbox}

\output{\@tempswafalse
\ifnum \outputpenalty>-\@MM \ifnum\outputpenalty<-10000 \@tempswatrue\fi\fi
\if@tempswa % special (float) output
   \message{Float handler: penalty=\the\outputpenalty}%
   \norm@L@output
\else
  \ifvoid\LW@saved % end of real page
     \message{End of real page}%
     \global\setbox\LW@saved\copy\@cclv % save page
     \setbox\@tempboxa\vbox{\unvbox\@cclv \unskip\unkern\unpenalty
       \unskip\unkern\unpenalty \unskip\unkern\unpenalty
       \setbox\@tempboxa\lastbox
       \LW@getlast@word\@tempboxa\LW@lastWbox
     }\ifnum\outputpenalty>-\@MM % not \supereject
       \xdef\LW@vsize{\the\vsize}\global\vsize\z@
     \else % \supereject, just output, don't look for word on next page
       \message{caused by super eject.}
       \global\setbox\@cclv\box\LW@saved
       \global\setbox\LW@nextfirstWbox\hbox{}%
       \norm@L@output
     \fi
  \else % saved page => just did tiny page to get next word
     \message{Just got next line:}%\tracingall\showboxdepth2 \showbox\@cclv
     \setbox\@tempboxa\vbox{\penalty12345\unvcopy\@cclv \LW@getall@boxes
       \ifvbox\LW@box \penalty12345\unvbox\LW@box \LW@getall@boxes\fi
       \ifvbox\LW@box \global\setbox\LW@nextfirstWbox\hbox{}\else
         \LW@getfirst@word\LW@box\LW@nextfirstWbox
       \fi}%  Return tiny page to page list:
     \unvbox\@cclv \ifnum\outputpenalty<\@M \penalty\outputpenalty\fi
     \global\vsize\LW@vsize\relax
     \setbox\@cclv\box\LW@saved
     \norm@L@output
\fi\fi}

% globally get last "word" from a box (#1) into another box (#2)
\def\LW@getlast@word#1#2{\setbox\@tempboxa\vbox{\hsize\wd#1\@parboxrestore
  \hyphenpenalty\@M \exhyphenpenalty\@M \hbadness\@MM
  \rightskip\fill \looseness\@M \linepenalty-\@lowpenalty
  \noindent\unhbox#1\endgraf
  \unskip\unkern\unpenalty \global\setbox\LW@box\lastbox
  }\LW@repack{#2}}

% globally get first "word" from a box (#1) into another box (#2)
\def\LW@getfirst@word#1#2{\setbox\@tempboxa\vbox{\@parboxrestore
  \parshape\thr@@ \z@\z@ \z@\z@ \z@\maxdimen \parfillskip\fill
  \hyphenpenalty\@M \exhyphenpenalty\@M \hbadness\@MM
  \ifhbox#1\noindent
   \vadjust{\penalty12345}\penalty-\@M\unhbox#1 % eliminate previous \leftskip
  \else\ifvbox#1\penalty12345\unvbox#1\fi\fi
  \endgraf
  \@tempcnta\z@  \LW@getall@boxes}\LW@repack{#2}}

% Go through a vertical list that starts with special penalty
\def\LW@getall@boxes{\global\setbox\LW@box\lastbox \unskip\unkern \unskip\unkern
  \let\@tempa\relax
  \ifvoid \LW@box \advance\@tempcnta\@ne \else \@tempcnta\z@ \fi
  \ifnum\lastpenalty=12345 \else \unpenalty\fi
  \ifnum\lastpenalty=12345 \else \unpenalty\fi
  \ifnum\lastpenalty=12345 \else \ifnum\@tempcnta<5
    \let\@tempa\LW@getall@boxes \fi \fi \unpenalty \@tempa}

% Put contents of \LW@box into hbox #1
\def\LW@repack#1{\global\setbox#1\hbox
  {\ifhbox\LW@box\unhbox\LW@box\unskip\unskip\unpenalty\unskip
    \else\ifvbox\LW@box\box\LW@box\fi\fi}}

\def\ps@fwlwhead{\let\@mkboth\@gobbletwo
 \def\@oddhead{[\copy\LW@firstWbox]\hfil[\copy\LW@lastWbox]}\let\@evenhead\@oddhead
 \def\@oddfoot{\hfil\thepage\hfil[\copy\LW@nextfirstWbox]}%
 \def\@evenfoot{[\copy\LW@nextfirstWbox]\hfil\thepage\hfil}%
 \def\chaptermark##1{}\def\sectionmark##1{}\def\subsectionmark##1{}%
 }



