summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/ltxmisc/fwlw.sty
blob: 17498f0bd51b3174b71e5e75fa60cec3f444d0d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
%  F W L W . S T Y  ( First Word, Last Word )
%
%  Donald Arseneau  (1993, 1995)
%
%  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.  The `words'
%  you see may not be real words, but any unbreakable object.
%
%  Such labelling does not make sense when \chapter generates a page
%  break, so 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".  There is a problem when footnotes split: the "next word"
%  is blank.
%
%  Two pagestyles are defined to print these words: \pagestyle{NextWordFoot}
%  which helps you read ahead to the word on the next page; and \pagestyle
%  {fwlwhead} which is like the headers in a lexicon.  Or you can use the
%  words in your own page-style...
%  The words are available in the box registers:
%     \FirstWordBox   -  first word on this page
%     \NextWordBox    -  first word on next page
%     \LastWordBox    -  last word on this page
%  Use them in your header lines like: \copy\LastWordBox.
%
%  Note that `words' may be things like:
%    - two~words
%    - [ ]Word  ( [ ] represents a parindent box)
%    - a whole displayed equation
%    - the first column of an aligned equation
%    - anomalously blank, if there are \writes or split footnotes etc.
%    - partial words like  par-  or  -tial.
%
%  An entirely different approach is possible using \mark and \obeyspaces,
%  and would have different problems.  The problems with catcode changes
%  may be more or less serious for your particular application.  You are
%  welcome to write a package using that method.  The best solution would 
%  involve \mark and an input filter program to 
%  `\w{tag} \w{each} \w{word}, \w{in} \w{some} \w{way}.'

\mathchardef\LW@pen 12345
\newbox\FirstWordBox     \global\setbox\FirstWordBox\hbox{}
\newbox\NextWordBox      \global\setbox\NextWordBox\hbox{}
\newbox\LastWordBox      \global\setbox\LastWordBox\hbox{}
\newbox\LW@box           \global\setbox\LW@box\hbox{}
\newbox\LW@saved

\def\ps@fwlwhead{\let\@mkboth\@gobbletwo
 \def\@oddhead{\if@fcolmade\else \copy\FirstWordBox\hfil\copy\LastWordBox\fi}%
 \let\@evenhead\@oddhead % no word-heads on float pages.
 \let\@oddfoot\@empty\let\@evenfoot\@oddfoot
 \let\chaptermark\@gobble\let\sectionmark\@gobble\let\subsectionmark\@gobble
 }

\def\ps@NextWordFoot{\let\@mkboth\@gobbletwo
 \let\@oddhead\@empty\let\@evenhead\@oddhead
 \def\@oddfoot{\hfil\thepage\hfil\llap{\copy\NextWordBox}}\let\@evenfoot\@empty
 \let\chaptermark\@gobble\let\sectionmark\@gobble\let\subsectionmark\@gobble
 }

%  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\FWLWnorm@L@output{\the\output}

\output{\@tempswafalse
\ifnum \outputpenalty>-\@MM \ifnum\outputpenalty<-\@M \@tempswatrue\fi\fi
\if@tempswa % special (float) output
%  \message{Float handler: penalty=\the\outputpenalty}%
   \FWLWnorm@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\LastWordBox
     }\ifnum\outputpenalty>-\@MM % not \supereject
       \xdef\LW@vsize{\global\vsize\the\vsize 
          \global\holdinginserts\the\holdinginserts}%
       \global\vsize\z@ \global\holdinginserts\@ne 
     \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\NextWordBox\hbox{}%
       \FWLWnorm@L@output
       \global\setbox\FirstWordBox\box\NextWordBox
     \fi
  \else % saved page => just did tiny page to get next word
%    \message{Just got next line:}{\tracingall\showboxdepth2 \showbox\@cclv}%
     \setbox\@tempboxa\vbox{\penalty\LW@pen\unvcopy\@cclv \LW@getall@boxes
       \ifvbox\LW@box \penalty\LW@pen\unvbox\LW@box \LW@getall@boxes\fi
       \ifvbox\LW@box \global\setbox\NextWordBox\hbox{}\else
         \LW@getfirst@word\LW@box\NextWordBox
       \fi}%  Return tiny page to page list:
     \unvbox\@cclv \ifnum\outputpenalty<\@M \penalty\outputpenalty\fi
     \LW@vsize\relax
     \global\setbox\@cclv\box\LW@saved
     \FWLWnorm@L@output
     \global\setbox\FirstWordBox\box\NextWordBox
\fi\fi}

% globally get last "word" from a box (#1) into another box (#2)
\def\LW@getlast@word#1#2{\setbox\@tempboxa\vbox{\hsize\maxdimen \@parboxrestore
  \hyphenpenalty\@M \exhyphenpenalty\@M 
  \rightskip\fill \looseness\@M \linepenalty\z@
  \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 \overfullrule\z@ \hfuzz\maxdimen
  \ifhbox#1\noindent
   \vadjust{\penalty\LW@pen}\penalty-\@M\unhbox#1% eliminate previous \leftskip
  \else\ifvbox#1\penalty\LW@pen\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=\LW@pen \else \unpenalty\fi
  \ifnum\lastpenalty=\LW@pen \else \unpenalty\fi
  \ifnum\lastpenalty=\LW@pen \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}}