\ifx\LABELS\relax\endinput\else\let\LABELS=\relax\fi % \input only once
%
% labels.tex: Macros to print address labels (and bulk letters).
% version: 1.0  release: 24 October 1991
%
% copyright (c) 1991 Marcel R. van der Goot
%	You can use these macros to typeset documents. You may
%	distribute this file freely, provided that you also distribute
%	the accompanying documentation.
%	    You may make changes to this file, or extract portions
%	of it for inclusion in other files, provided that
%	    (1) you change the name of the file;
%	    (2) you give proper credit and include copyright
%		information where applicable;
%	    (3) explain how an unchanged version can be obtained; and
%	    (4) document the usage of your macros/changes (if usage
%		of your macros is not worth documenting, they must not
%		be worth using).
%	You are not allowed to use the name ``Midnight Macros'' for
%	any changed files.
%	    The above rules for making changes do not apply where it
%	is explicitly noted in this file that something can be changed
%	to conform to your local installation.
%
% USAGE:
%   See the file labels.doc
%   You need Midnight/dolines.tex and Midnight/loop.tex to use these
%   macros.
%
% original: csvax.cs.caltech.edu [131.215.131.131] in pub/tex
%	    (use anonymous ftp). Also in various archives.
%
% Caltech, Pasadena  ---  Marcel van der Goot
%			  marcel@cs.caltech.edu
%			    Caltech 256--80
%			    Pasadena, CA 91125
%			    USA
%			    (818) 356--4603
%

% update history:
% version 1.0: This one.
%	release 24 Oct 1991: I undid the change from 6 Aug 1991: Matthias
%		Feyerabend suggested a more elegant change that has the
%		same result (involving \the\expandafter\lbl_txt#1).
%	release 6  Aug 1991: Dolines.tex was changed since the previous
%		release: it now calls \everyline with a single macro rather
%		than with the text of the line. This required a change in
%		the creation of \lbl_txt; \addlbl_txt was added.
%	release 14 Feb 1991: The original
%

%%%%%% CODE: (you don't need to read this to use the macros)

\input Midnight/dolines % CHANGE this filename to correspond to
			% your installation

%%%%%%% Registers
% All user-accessible registers. Some private registers are declared
% later.
% Individual labels:
\newdimen\vlblsize
\newdimen\hlblsize
\newskip\vindent
\newskip\hindent
\newdimen\lbloutline
\newtoks\beforelbl
\newtoks\afterlbl

% Labels on a page:
\newcount\vlbls
\newcount\hlbls
\newdimen\vfirst
\newdimen\hfirst
\newdimen\vinter
\newdimen\hinter

% We make `_' into a letter to make macros private
\vlbls=\catcode`\_ % minor trick to remember old value
\catcode`\_=11

\newbox\lbl_ % box in which a label is constructed


%%%%%%% Error message
% If a label is too large, we give an error message. \err_dim is the
% excess size of the label, \lbl_txt is the text of the label. \lbl_txt
% is set while reading the label, so that we can report which label is
% too large. Depending on the value of \err_act, more action is
% taken: 0 --> nothing, 1 --> print label anyway, others --> print
% this label on \lbl_log=lblerror.tex as well. \lbl_log is closed
% and an appropriate message printed by \close_log.

\newdimen\err_dim
\newtoks\lbl_txt
\newcount\err_act
\newcount\err_cnt
\newwrite\lbl_log

\let\erroraction=\err_act

\def\err_lbl#1% #1 = "wide" or "high"
   {{\global\advance\err_cnt by 1
     \newlinechar=`\^^J
     \immediate\write16{^^J**** Label is \the\err_dim\space too #1:}%
     \immediate\write16{\the\lbl_txt}%
     \ifcase\err_act
     \or\make_lbl
     \else\immediate\write\lbl_log{\the\lbl_txt}%
     \fi
   }}

\def\close_msg#1%
   {\ifnum\err_cnt>0 \immediate\write16{#1}%
    \fi
   }

\def\close_log
   {\ifcase\err_act
	 \close_msg{**** \the\err_cnt\space error(s) ****}%
    \or  \close_msg{**** \the\err_cnt\space label(s) with errors %
			 are included in the dvi file ****}%
    \else\immediate\closeout\lbl_log
	 \close_msg{**** \the\err_cnt\space error(s): see lblerror.tex ****}%
    \fi
   }

%%%%%%% Reading a label
% Every group of lines is set in a vbox, using dolines.tex (see dolines.doc).
% \lbl_before corresponds to \beforelines (see dolines), etc.
% Every line itself is set in an hbox. The sizes of the hboxes and
% vboxes are not specified here, because we want to do our own checking
% rather than rely on TeX's checking and error messages. The computation
% in \lbl_before is used to position the baseline of the first line
% independently of the height of that line. \vindent is similar to TeX's
% \topskip.

\def\lbl_before
   {\global\lbl_txt={}%
    \setbox\lbl_=\vbox\bgroup
		   \advance\vindent by -\baselineskip
		   \ifdim\vindent<0sp \vindent=0sp \fi
		   \vskip\vindent
		   \prevdepth=0sp
		   \the\beforelbl
   }

% #1 is always equal to `\_ln', which in turn expands to the line of text.
% That works fine with \hbox, but we must somehow expand \_ln first before
% we put it in \lbl_txt. That is what the second expandafter is for. The
% first expandafter is to expand \the\lbl_txt (and \_ln) before the '{' is
% read. Otherwise no expansion is done: TeX does not expand the tokens in
% the text of a token variable.
% --- thanks for this solution to Matthias Feyerabend.

\def\lbl_every#1%
   {\hbox{#1}%
    \global\lbl_txt=\expandafter{\the\expandafter\lbl_txt#1^^J}%
   }

\def\lbl_after
   {\the\afterlbl
    \egroup % closes \lbl_=\vbox{...}
    \check_lbl
   }

%%%%%%% Making a label
% \check_lbl checks whether the label is not too large, and, if not,
% calls \make_lbl. (\make_lbl can also be called from \err_lbl.)
% Note that \check_lbl only checks for the natural size of the label;
% if \hindent or \vindent have shrink components, the label may
% actually fit.

\def\check_lbl
   {\err_dim=\wd\lbl_ \advance\err_dim by \hindent
    \ifdim\err_dim>\hlblsize
         \advance\err_dim by -\hlblsize
	 \err_lbl{wide}%
    \else\err_dim=\ht\lbl_ \advance\err_dim by \dp\lbl_
	 \ifdim\err_dim>\vlblsize
	      \advance\err_dim by -\vlblsize
	      \err_lbl{high}%
	 \else\make_lbl
    \fi  \fi
   }

\def\make_lbl
   {\setbox\lbl_=\vbox to \vlblsize{\unvbox\lbl_ \vss}%
    \setbox\lbl_=\hbox to \hlblsize
	{\kern -\lbloutline \vrule width\lbloutline
	 \hskip\hindent \box\lbl_ \hss
	 \vrule width\lbloutline \kern -\lbloutline
	}%
    \setbox\lbl_=\vbox
	{\kern -\lbloutline \hrule height\lbloutline
	 \box\lbl_
	 \hrule height\lbloutline \kern -\lbloutline
	}%
    \add_to_row
   }

%%%%%%% Making a page
% \lbl_out takes the label constructed in \lbl_ and adds it to the current
% row. If the row is full, as counted by \h_cnt, the row is added
% to the current page. Similarly, if \v_cnt indicates a full page,
% the page is shipped out. (Note: There is no interline glue between
% rows because of the way \unvbox does (not) affect \prevdepth.)
% \finish_page ships out any remaining incomplete page.
% \count1 is used to count the labels (this is only used to report
% to the user when a page is shipped out).

\newbox\lbl_page
\newbox\lbl_row
\newcount\v_cnt
\newcount\h_cnt

\def\add_to_row
   {\ifnum\h_cnt=0
	 \global\setbox\lbl_row=\hbox{\kern\hfirst \box\lbl_}%
    \else\global\setbox\lbl_row=
			\hbox{\unhbox\lbl_row \kern\hinter \box\lbl_}%
    \fi
    \global\advance\h_cnt by 1 \global\advance\count1 by 1
    \ifnum\h_cnt<\hlbls
    \else\add_to_page \global\h_cnt=0
    \fi
   }

\def\add_to_page
   {\ifnum\v_cnt=0
	 \global\setbox\lbl_page=\vbox{\kern\vfirst \box\lbl_row}%
    \else\global\setbox\lbl_page=
			\vbox{\unvbox\lbl_page \kern\vinter \box\lbl_row}%
    \fi
    \global\advance\v_cnt by 1
    \ifnum\v_cnt<\vlbls
    \else\shipout\box\lbl_page \global\v_cnt=0 \global\advance\count0 by 1
    \fi
   }

\def\finish_page
   {\ifnum\h_cnt>0 \add_to_page \fi
    \ifnum\v_cnt>0 \shipout\box\lbl_page \global\advance\count0 by1 \fi
   }

%%%%%%% Typesetting labels
% In \setup_lbl the \bgroup is to prevent some changes from continuing
% after \endlabels (e.g., catcode changes). Of course, we could also have
% reset them to the (presumed) old values in \endlabels. And anyway,
% it is a rather unnecessary refinement, since it doesn't make much
% sence to combine typesetting labels with other things in the same
% TeX run. We prevent changes of \erroraction while labels are being
% typeset, since such changes would cause confusion with respect to
% the log file. (Another unnecessary refinement: if you change the
% action you deserve what you get.)
% The \hsize is set properly in case \beforelbl or \afterlbl contains
% horizontal material (this will be typeset as a normal paragraph).
% It also allows the use of \line in these token registers.

\def\catcode_lbl{\catcode`\&=12 \catcode`\#=12 }

\def\setup_lbl
   {\vfill\supereject
    \ifcase\err_act\or\else
	\immediate\openout\lbl_log=lblerror.tex  %<- significant space
    \fi
    \let\beforelines=\lbl_before \let\afterlines=\lbl_after
    \let\everyline=\lbl_every
    \let\finishdolines=\endlabels \def\enddolines{\endlabels}%
    \bgroup
    \dimen0=\hlblsize \advance\dimen0 by-\hindent
    \hsize=\dimen0
    \let\erroraction=\relax \err_cnt=0
    \h_cnt=0 \v_cnt=0 \global\count1=0
    \voffset=-1in \hoffset=-1in
    \catcode_lbl
   }

\def\endlabels
   {\finish_page
    \egroup
    \close_log
   }

\def\beginlabels{\setup_lbl \begindolines}

\def\labelfile#1{\setup_lbl \filedolines{#1}\endlabels}


%%%%%%% Typesetting bulk letters
% This is kept quite simple: Labels are read one by one from a file,
% and consist of a vbox with an hbox for each line. No extra indentations
% or other frills. After each label has been read, we simply \input the
% bulk letter. In the letter, \bulkaddress will typeset the label.
% Just before we input the letter, we set \end=\relax, just in case the
% letter ends with \bye. (This is better than setting \bye=\relax, since
% \bye may insert extra material.) The grouping from \filedolines will
% restore the original \end.

\def\bulk_before{\setbox\lbl_=\vbox\bgroup}
\def\bulk_every#1{\hbox{#1\strut}}

\def\bulk_after
   {\egroup % closes \setbox\lbl_=\vbox\bgroup
    \catcode_plain
    \let\end=\relax
    \input\bulk_in %
    \vfill\supereject
    \catcode_lbl
   }

\def\bulkaddress{\copy\lbl_}

\def\bulk#1#2% addresses, letter
   {\vfill\supereject
    \edef\catcode_plain{\catcode`\noexpand\&=\the\catcode`\&%
			\catcode`\noexpand\#=\the\catcode`\#}%
    \let\beforelines=\bulk_before \let\afterlines=\bulk_after
    \let\everyline=\bulk_every
    \catcode_lbl
    \def\bulk_in{#2}%
    \filedolines{#1}%
    \catcode_plain
   }


%%%%%%% Initial values
% \errorcontextlines (exists in TeX 3.0 and later versions) is set in
% order to not unnecessarily confuse unexperienced users. Supposedly,
% the macros above don't cause errors. Any errors are most likely
% caused by something in \beforelines or \afterlines.

\catcode`\_=\vlbls % restore catcode

\ifx\errorcontextlines\undefined % \then old TeX version
\else\errorcontextlines=-1
\fi

\erroraction=2
\lbloutline=0sp
\beforelbl={}
\afterlbl={}

% The following defaults are rather arbitrary, in practice the user
% always has to set these values.
\vlblsize=5cm
\hlblsize=10cm
\vindent=1.3\baselineskip
\hindent=0.5cm

\vlbls=5
\hlbls=2
\vfirst=1cm
\hfirst=5mm
\vinter=2mm
\hinter=2mm

%%%%%%%
