% \title{Addresslists with \LaTeX}
% \author{Tobias Spribille}
% \maketitle
%\iffalse
%<*driver>
\documentclass{ltxdoc}
\begin{document} \DocInput{adrlist.dtx} \end{document}
%
%\fi
% \section{User's Guide} \DescribeMacro{\ForEachAdress}
% The package |adrlist| provides the macro |ForEachAddress| as follows:
%
% |\ForEachAdress{|\meta{addressfile}|}{|\meta{commands}|}|
%
% \noindent The parameters are:
% \begin{description}
% \item[addressfile] Name of a file containing the addresses in the
% following structure: \label{fileformat}
%
% \DeleteShortVerb{\|}\MakeShortVerb{\!}
% \begin{tabular}{|l|l|}
% \hline
% !
! & Title, degree, e.g. "Dipl.-Inf."\\ \hline
% !! & how to address the person \\ \hline
% !! & the sex, for grammatical correctness \\ \hline
% !! & First name \\ \hline
% !! & Name \\ \hline
% !-- begin address --! & delimiter \\ \cline{2-2}
% n lines of address & address with variable length\\ \cline{2-2}
% !-- end address --! & delimiter, to be typed exactly this way \\ \hline
% Telephone: !! & These entries may appear \\ \cline{1-1}
% Telefax: !! & in any order. They are \\ \cline{1-1}
% EMail: !! & distinguished through the \\ \cline{1-1}
% Private number: !! & keywords before the colon ":".\\
% \hline
% \end{tabular}
% \DeleteShortVerb{\!}\MakeShortVerb{\|}
% \item[commands] \LaTeX-commands to typeset the read data. You can use these
% commands defined by the package in order to access the address data:
%
% \DeleteShortVerb{\|}\MakeShortVerb{\!}
% \begin{tabular}{|l|l|}
% \hline
% !\Title! & Title \\ \hline
% !\Opening! & Opening \\ \hline
% !\Sex! & Sex \\ \hline
% !\Firstname! & First name \\ \hline
% !\Name! & Name\\ \hline
% !\Address! & Address. The lines are separated by !\\! \\ \hline
% !\Telephone! & Telephone number \\ \hline
% !\Telefax! & Telefax number \\ \hline
% !\EMail! & EMail address \\ \hline
% !\PrivateNumber! & Private telephone number \\
% \hline
% \end{tabular}
% \DeleteShortVerb{\!}\MakeShortVerb{\|}
% \end{description}
% \section{The Macros}
% \subsection{Declarations}
% This file provides the macro package |adrlist|. For various loops and conditions
% we require the |ifthen|-package.
% \begin{macrocode}
\ProvidesPackage{adrlist}[1995/12/21]
\RequirePackage{ifthen}
% \end{macrocode}
% Declare some variables: |Rest| controls the outer loop, which reads several
% entries out of the address database. If there are lines left in the file, it is true.
% |AddressLoop| is used for reading the adresses with variable
% length. |Communication| is a counter to repeat four times the recognition of the
% keywords for phone number, email etc.
% \begin{macrocode}
\newboolean{AddressLoop}
\newboolean{Rest}\setboolean{Rest}{true}
\newcounter{Communication}
% \end{macrocode}
% \subsection{Helper macros}
% \begin{macro}{\ifstringcompare}
% Compare two entire strings, given in the two parameter variables, and not only
% tokens, like \TeX{} does.
% \begin{macrocode}
\newcommand{\ifstringcompare}[4]{%
\begingroup
\let\protect=\noexpand
\edef\0{#1}\edef\1{#2}%
\expandafter\endgroup\ifx\0\1#3\else#4\fi}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\concat}
% Concatenate two lines of the address, with |\\| as a delimiter, as it is required
% by e.g. the |letter| style.
% \begin{macrocode}
\newcommand{\concat}[2]{#1\\#2}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\keyword}
% Extract the keyword out of a line of the form \meta{keyword}|:|\meta{contents},
% i.e. the part before the colon. The pipe symbol may be replaced by any other
% character that won't appear in the address data.
% \begin{macrocode}
\def\keyword#1:#2|{#1}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\contents}
% Like |\keyword|. Extracts the contents of the line, e.g. the phone number.
% \begin{macrocode}
\def\contents#1:#2|{#2}
% \end{macrocode}
% \end{macro}
% \newpage
% \subsection{The user macro}
% \begin{macro}{\ForEachAddress}
% This macro is the one the user directly calls. It opens the file given in |#1| and
% reads all the addresses in a loop. For each address the \LaTeX-commands in |#2|
% are executed to typeset the address in the document. After the whole file is read,
% it is closed again.
% \begin{macrocode}
\newcommand{\ForEachAddress}[2]
{
\newread\File \openin\File=#1
\whiledo{\boolean{Rest}}
{ \ReadNextAddress{\File}
\ifthenelse{\boolean{Rest}}{#2}{}
}
\closein\File
}
% \end{macrocode}
% \end{macro}
% \subsection{Main macrocode}
% \begin{macro}{\ReadNextAddress}
% Here we read the next address out of the file given as |#1| and save the read data
% into the respective variables. For the structure of the address file and
% the variable names, confer to section \ref{fileformat}.
% \begin{macrocode}
\newcommand{\ReadNextAddress}[1]{
\ifthenelse{\boolean{Rest}}{
\read#1 to \Title
\ifeof#1\setboolean{Rest}{false}
\else % If last address already is read, EOF should appear here
\ifthenelse{\boolean{Rest}}
{\read#1 to \Opening
\ifeof#1\setboolean{Rest}{false}\fi
}{}
\ifthenelse{\boolean{Rest}}
{\read#1 to \Sex
\ifeof#1\setboolean{Rest}{false}\fi
}{}
\ifthenelse{\boolean{Rest}}
{\read#1 to \Firstname
\ifeof#1\setboolean{Rest}{false}\fi
}{}
\ifthenelse{\boolean{Rest}}
{\read#1 to \Name
\ifeof#1\setboolean{Rest}{false}\fi
}{}
\ifthenelse{\boolean{Rest}}
{\read#1 to \Dummy
\ifeof#1\setboolean{Rest}{false}\fi
}{}
\setboolean{AddressLoop}{true}
\def\Emptystring{} \let\Address=\Emptystring
\def\Delimiter{-- end address -- }
% \end{macrocode}
% Read Address, until |-- end address --| appears.
% \begin{macrocode}
\whiledo{\boolean{AddressLoop}}
{
\ifRest \read#1 to \Buffer \fi
\ifeof#1\setboolean{Rest}{false}\fi
\ifstringcompare{\Buffer}{\Delimiter}
{\setboolean{AddressLoop}{false}}{}
\ifthenelse{\boolean{AddressLoop}}
{
\ifstringcompare{\Emptystring}{\Address}
{
\let\Address=\Buffer % Don't add delimiters the first time
}
{
\begingroup % keep redefinition of \\ local
\let\protect=\noexpand
\def\\{\noexpand\\}% make \\ not expandable
\edef\x{\endgroup
\def\noexpand\Address{\concat\Address\Buffer}%
}\x
}
}{}
}
% \end{macrocode}
% Four informations are left. The keyword is extracted from |\Buffer| and compared
% with the defined keywords. If the comparison succeeds, the correct variable is set.
% \begin{macrocode}
\def\KeyWTelephone{Telephone}
\def\KeyWTelefax{Telefax}
\def\KeyWEMail{EMail}
\setcounter{Communication}{0}
\whiledo{\value{Communication}<4}%
{
\ifthenelse{\boolean{Rest}}{
\read#1 to \Buffer
\edef\KeyW{\expandafter\keyword\Buffer|}
\ifstringcompare{\KeyW}{\KeyWTelephone}
{
\edef\Telephone{\expandafter\contents\Buffer|}
}
{
\ifstringcompare{\KeyW}{\KeyWTelefax}
{
\edef\Telefax{\expandafter\contents\Buffer|}
}
{
\ifstringcompare{\KeyW}{\KeyWEMail}
{
\edef\EMail{\expandafter\contents\Buffer|}
}
{
\edef\PrivateNumber{\expandafter\contents\Buffer|}
}
}
}
\ifeof#1\setboolean{Rest}{false}\fi
}{}
\stepcounter{Communication}
}
\fi
}{}
}
% \end{macrocode}
% \end{macro}