% 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{}% }