% Merge File Model Macro Definition File
\catcode`*=11
\catcode`"=\active
\catcode`,=\active
\catcode`@=\active
\newbox\FirstUp
\newbox\SecondUp
\newbox\ThirdUp
\newcount\*first           \*first=0       % first token field
\newcount\*index           \*index=0       % field index
\newcount\*lastentry       \*lastentry=0   % last token filed
\newcount\*letternumber    \*letternumber=0 % letter number from start
\newcount\LblsUp           \LblsUp=1       % number of labels per line
\newcount\LblsAcross       \LblsAcross=0   % counter for labels accross
\newdimen\LblMat           \LblMat=0pt     % left and right label margins
\newdimen\LblHt            \LblHt=0in      % vertical label size
\newdimen\LblWd            \LblWd=0in      % horozontal label size
\newif\if*check            \*checkfalse    % datacheck for manual entry
\newif\if*lbfopen          \*lbfopenfalse  % check for open label file
\newtoks\*csnametoks       \*csnametoks={} % tokens for field names
\newtoks\*maillblfmt       \*maillblfmt={} % label sheet format code
\newtoks\*addrlbl          \*addrlbl={}    % address label tokens
\newwrite\*labels                          % create label filee

\gdef,{\char'54{}}%
% Datacheck forces a print letter after each set of fields
\def\datacheck{\global\*checktrue}%
\def@{\ifnum\*index>0
     \global\*index=\*first         % reset index
     \if*check
       \global\advance\*letternumber by1
       \immediate\write16{Letter number \the\*letternumber.
        First Data Field: (\the\toks\*first) . . .
          Last Data Field: (\the\toks\*lastentry ). }
       \fi        % write to log file for data check
     \*prnletter                    % print current data
     \fi
}   % end of @ definition

% Take user defined names to build control sequences
\def\fieldnames#1{\par
 \global\advance\count15 by 1 % new token register
 \global\*first=\count15 % first new token register
 \parsenames#1\end}% end fieldnames markup

% Separate name fields into individual entries
\def\parsenames#1{\ifx#1\end
 \createfield
 \let\next=\relax
 \global\*lastentry=\count15
 \global\*index=\*first
 \*csnametoks={}
 \else
   \ifx#1,
     \createfield
     \global\advance\count15 by 1
     \*csnametoks={}
     \let\next=\parsenames
     \else \*csnametoks=\expandafter{\the\*csnametoks#1}
        \let\next=\parsenames
        \fi\fi
 \next}% end parsenames markup

% CREATEFIELD create control sequence names from name field entries
\def\createfield{\expandafter\xdef\csname\the\*csnametoks\endcsname
 {\noexpand\the\toks\the\count15 }}% end createfield markup

% DEFINE " as name of merge command
\def"#1"{% set quote marks as active macro and delimiter
 \ifnum\*index=0 \global\*index=\*first\fi
 \global\toks\*index={#1}           % gather argument in token variable
 \ifnum\*index<\*lastentry          % continue gathering process
   \gdef,{\gdef,{\char'54{}}}%      % drop , in data but not in text
   \global\advance\*index by1       % index by 1
   \ignorespaces                    % eliminate spurious spaces
   \else                            % end process
     \global\*index=0
     \if*check
       \global\advance\*letternumber by1
       \immediate\write16{Letter number \the\*letternumber.
        First Data Field: (\the\toks\*first) . . .
          Last Data Field: (\the\toks\*lastentry ). }
       \fi        % write to log file for data check
     \*prnletter                    % print current data
     \fi}% end define " as macro name

% Merge letter text file merged for each data record
\def\*prnletter{% Print the letter text with current name/address fields
 \catcode`"=12\catcode`@=3          % set " and @ to normal catcodes
 \newpage                           % start new page for each letter
 \setpagenumber{1}                  % reset page number
 \inputletter                       % new page then get letter text file
 \*savelabels{\*setlabel}           % save address label information
 \catcode`"=\active\catcode`@=\active % reset catcodes for markup defs
 \relax}% end prnletter markup

% Give filename for letter text
\def\documentfilename#1{\gdef\inputletter{\input #1 }}%

% Give maillist data filename
\def\datafilename#1{\input #1 }%

% Print no empty lines with the line break markup
\def\noemptyspace#1#2{\edef\V{#1}\edef\W{\empty}%
 \ifx\V\W% do nothing if empty argument
   \else #1#2\fi% if not empty replace argument with the line break
}% end no emptyspace
\let\nes=\noemptyspace % set abbreviation


% SAVELABELS ships information for labels to the label file
\def\*savelabels#1{% Write Mail Label Information to TEXT1$$.LABEL
 \if*lbfopen % do nothing if file TEXT1$$.LABEL already open
   \else \immediate\openout\*labels=text1$$.label % open TEXT1$$.LABEL
      \immediate\write\*labels{\the\*maillblfmt} % write format
      \global\*lbfopentrue\fi        % set open flag
 \global\advance\LblsAcross by1 % set label postion pointer
 \ifnum\LblsAcross>\LblsUp \global\LblsAcross=1 \fi
 \edef\T{% create labels
   \ifnum\LblsAcross=1 \setbox\FirstUp=\fi % left label
   \ifnum\LblsAcross=2 \setbox\SecondUp=\fi% center label
   \ifnum\LblsAcross=3 \setbox\ThirdUp=\fi % right label
   \vtop to\LblHt{\hsize=\LblWd \leftskip=\LblMat \rightskip=\LblMat
     \parindent=0pt #1\par\vfil} % make label to label size and width
   \ifnum\LblsAcross=\LblsUp % print labels
     \ifcase\LblsUp% case 0, no labels specified
        \or\setbox\SecondUp=\null \setbox\ThirdUp=\null % one label
        \or \setbox\ThirdUp=\null   % two labels
        \fi% end case               % three label default
     \line{\box\FirstUp\box\SecondUp\box\ThirdUp\hfil}
     \fi}% end definition of T
 \immediate\write\*labels{\T} % write information to file
}% end save labels definition

% Flushlabels prints any unprinted labels remaining in the markup
\def\*flushlabels{% print any remaining boxed labels
 \ifcase\LblsUp % case ), no labels specified
   \or \setbox\SecondUp=\null \setbox\ThirdUp=\null % one label
   \or \setbox\ThirdUp=\null        % two labels
   \fi% end case                    % three label default
 \immediate\write\*labels{\line{\box\FirstUp\box\SecondUp\box\ThirdUp
   \hfil}}%
}% end flush any remaining labels

% Print the label file TEXT1$$.LABEL
\def\printlabels{\newpage            % end last letter
   \*flushlabels                    % print any remaining labels
   \immediate\closeout\*labels      % close data file
   \setpagenumber{99}               % labels begin on page 99
   \input text1$$.label             % input the address label data file
}% end print mailing labels

\def\addresslabelformat#1{\global\*addrlbl={#1}}%
\*addrlbl={}

\def\*setlabel{\the\*addrlbl}%

% Set format for the mailing labels
\def\maillabelformat#1{% Sets dimensions and margins of each label
   \def\labelsetup##1{\global\*maillblfmt={##1}}%
   \def\numberoflabelsperline##1{\global\LblsUp=##1}%
   \def\labelheight##1{\global\LblHt=##1}%
   \def\labelwidth##1{\global\LblWd=##1}%
   \def\labelmat##1{\global\LblMat=##1}%
 #1}% end mail label format
\let\mlfmt=\maillabelformat % set abbreviation
\catcode`*=12

% Set defaults for the mailing labels
% Maillabelformat sets the page and label information for mailing labels
\maillabelformat{\labelsetup{% Sets page and margin settings
                   \raggedbottom
                   \parskip=0pt plus0pt minus0pt
                   \runningheadformat{\bothpages{\line{}}}
                   \pageformat{\topmargin{1in}
                               \bottommargin{0pt}
                               \leftmargin{0pt}
                               \rightmargin{0pt}}% end page format
                            }% end labelsetup
                \numberoflabelsperline{3}%         three labels max
                \labelheight{1in}
                \labelwidth{2.75in}
                \labelmat{.25in}
}% end mail label format