%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                              %
%                This is WINDOW.STY               (Elmar Schal\"uck Apr 1991)  %
%                                                                              %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\message{This is WINDOW.STY   by Elmar Schalueck    April 1991}
%   These routines and macros are mainly due to Alan Hoenig
%   I myself found them in a lovely book named
%   \TeX: applications, uses, methods (Malcolm Clark, ed.),
%   Horwood, New York 1990
%   Please report errors, suggestions for better versions, etc. to
%   elmar@uni-paderborn.de
%
\newdimen\@totalheight                   % the height of the included box
\newdimen\@wordskip                      % interspace between box and text
\newcount\@numberlines                   % lines corresponding to boxheight
\newdimen\@tempdim                       % vskip box to have middle height
\def\z@pt{0pt}
\newdimen\point@strut                    % help dimension
\newdimen\strut@depth \newdimen\strut@height        % approximate values
\newcount\n@                             % count value for parshaping
\newcount\old@vbadness                   % backup value
\newcount\@top                           % number of full lines
\newcount\@window                        % number of window lines
\newdimen\shave@height                   % backup values
\newdimen\old@split@top@skip \newdimen\old@prevdepth
\newdimen\old@lineskip
\newdimen\@side                          % length of windowtext left and right
\newdimen\left@side \newdimen\right@side % text left and right
\newcount\ratio@left                     % ratio of text left versus right
\newcount\ratio@right
\newcount\ratio@sum
\newcount\ratio@zero                     % instead of a \newif
\newtoks\parshape@spec                   % build the wanted parshape
\newbox\window@parbox                    % the textbox with empty window
\newbox\left@box                         % help box to reassemble line
\newbox\right@box
\newbox\build@par                        % text before reassembling
\newbox\in@window                        % what to put in the window
%
\def\windowbox[toplines: #1][inwindow: #2][ratio: #3 #4]#5\par{%
%  #1 number of lines before the window starts
%  #2 what will be displayed in the window
%  #3 how many parts of the text will be on the left side of the window
%  #4 how many parts of the text will be on the right side of the window
%  #5 the actual text of the window
\old@vbadness=\vbadness \vbadness=10000
\@top=#1
\setbox\in@window\hbox{#2}
\ratio@left=#3
\ratio@right=#4
\ratio@zero=0              % ratio@zero = 0 iff text appears on
			      % both sides of  the window and cutting
			      % and reassembling must be done.
\ifnum\ratio@left=0\ratio@zero=1\fi
\ifnum\ratio@right=0\ratio@zero=1\fi
\calculate@dimens          % collect all values that are necessary
\create@parshapespec       % create the parshape of the text
\setbox\build@par=\vbox{\parshape=\n@ \the\parshape@spec \strut#5}
			      % build the paragraph
\ifnum\ratio@zero=1
\let\window@parbox=\build@par   % the paragraph is ok
\else\open@window\fi            % cut and reassemble
\vskip0.5\@tempdim
\vskip\@top\baselineskip        % place the box inside the window
\noindent
\ifnum\ratio@left=0
\else\hskip\left@side
\hskip\@wordskip
\fi     
\box\in@window                  % jump back to the normal beginning of
\par\nobreak                    % the paragraph. Avoid page breaks
\vskip-0.5\@tempdim
\vskip-\@totalheight
\vskip-\@top\baselineskip
\box\window@parbox              % place the actual text
\vbadness=\old@vbadness                  % restore old settings
\splittopskip=\old@split@top@skip
}
%
\def\open@window{%                      % cut and paste
\old@split@top@skip=\splittopskip \global\splittopskip=0pt
\ifnum\@top=0
\old@prevdepth=\strut@depth\else
\shave@height=\@top\baselineskip
\advance\shave@height by-\strut@depth
\global\setbox\window@parbox=\vsplit\build@par to \shave@height
\old@prevdepth=\dp\window@parbox
\fi
%%          \window@parbox contains the top part of the paragraph
\count10=\@numberlines             % for lines := 1 to @numberlines do
\shave@height=\strut@height
\loop \setbox\left@box=\vsplit\build@par to\shave@height
\setbox\right@box=\vsplit\build@par to\shave@height
%% the left and the right boxes of one line are built
\advance\count10 by-1 \make@line[\left@box,\right@box]
%% now they are reassembled
\ifnum\@top=0                 % if in first line without toplines
\ifnum\count10=\@numberlines
\global\setbox\window@parbox\vbox{\box0}    % initiate window@parbox
\else\addline@to@windowpar                  % else addlines
\fi
\else\addline@to@windowpar
\fi
\ifnum\count10>0 \repeat    % end of window-loop
%%      \window@parbox has the window part too
%%      paste the bottom
\old@lineskip=\lineskip
\global\setbox\window@parbox=\vbox{\prevdepth=\old@prevdepth%
\lineskip=1.5pt                       % This value doesn't seem to fit
					 % for big fontsizes
\unvbox\window@parbox\box\build@par}
\lineskip=\old@lineskip
}
%
\def\calculate@dimens{%
\setbox0\hbox{[}         % to calculate strut@height and strut@depth
\point@strut=\baselineskip
\advance\point@strut by -\ht0
\advance\point@strut by -\dp0
\divide\point@strut by 2
\global\strut@height=\ht0         % just approximate values
\global\strut@depth=\dp0
\global\advance\strut@height by\point@strut
\global\advance\strut@depth by\point@strut
\global\setbox\strutbox=\hbox{\vrule height\strut@height
depth\strut@depth width0pt}                    % adjust the \strutbox
\global\@totalheight=\ht\in@window
\global\advance\@totalheight by\dp\in@window   % the total height of the
						  % included window
\global\@numberlines=\@totalheight
\global\divide\@numberlines by\baselineskip
\global\@tempdim=\baselineskip
\global\multiply\@tempdim by-\@numberlines
\global\advance\@tempdim by\@totalheight
\ifdim\@tempdim>0.3pt%
 \global\advance\@numberlines by 1
 \global\@tempdim=\baselineskip
 \global\multiply\@tempdim by\@numberlines
 \global\advance\@tempdim by-\@totalheight
\fi                                            % number of lines for the window
						  % and additional vskip for window
\global\@wordskip=\fontdimen2\font
\global\@window=\@numberlines
\global\@side=\hsize
\global\advance\@side by-\wd\in@window
\global\advance\@side by-\@wordskip
\ifnum\ratio@zero=0\global\advance\@side by-\@wordskip\fi
\ratio@sum=\ratio@left
\advance\ratio@sum by\ratio@right
\global\left@side=\@side
\global\multiply\left@side by\ratio@left
\global\divide\left@side by\ratio@sum
\global\right@side=\@side
\global\multiply\right@side by\ratio@right
\global\divide\right@side by\ratio@sum         % left side and right side
						  % according to the chosen ratio
}
%
\def\create@parshapespec{%
\global\n@=\@top                               % number of lines for parshape
\global\advance\n@ by\@window
\ifnum\ratio@zero=0\global\advance\n@ by\@window\fi
\global\advance\n@ by1
\global\parshape@spec={}                       % initialize parshape@spec
\count10=\@top                                 % for i := 1 to @top do
\ifnum\@top>0{                                 % add complete lines to shape
\loop \global\parshape@spec=\expandafter{\the\parshape@spec \z@pt\hsize}
\advance\count10 by-1 \ifnum\count10>0 \repeat
}\fi
\count10=\@window                              % for i := 1 to @window do
\loop                                          % add two shorter lines
\ifnum\ratio@zero=0         % both ratio values \neq 0
\global\parshape@spec=\expandafter{\the\parshape@spec
\z@pt\left@side \z@pt\right@side}
\else                       % one ratio value is zero
\ifnum\ratio@left=0
\@side=\hsize\advance\@side by-\right@side     % window at the left side
\global\parshape@spec=\expandafter{\the\parshape@spec
\@side\right@side}\fi
\ifnum\ratio@right=0\global\parshape@spec=\expandafter{\the\parshape@spec
\z@pt\left@side}\fi                            % window at the right side
\fi
\advance\count10 by-1 \ifnum\count10>0 \repeat % end of loop
\global\parshape@spec=\expandafter{\the\parshape@spec \z@pt\hsize}
}                                              % add full line to shape
%
%   unwrap the vertical glue and remove the final glue
\def\unwrap#1#2{\unvbox#1 \setbox#1=\lastbox
\setbox#1=\hbox to#2{\strut\unhbox#1 \unskip}%
}
%
%  make a line of two halfs
\def\make@line[#1,#2]{%
\unwrap\left@box\left@side \unwrap\right@box\right@side
\setbox0=\hbox to\hsize{\box#1\hss\box#2}%
}
%
\def\addline@to@windowpar{%       add the reassembled lines to the output
\global\setbox\window@parbox=\vbox{\prevdepth=\old@prevdepth
\unvbox\window@parbox \box0}%
\old@prevdepth=\dp\window@parbox
}
%
%

