% \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 % !<opening>! & how to address the person \\ \hline % !<sex>! & the sex, for grammatical correctness \\ \hline % !<first name>! & First name \\ \hline % !<name>! & 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: !<telephone number>! & These entries may appear \\ \cline{1-1} % Telefax: !<telefax number>! & in any order. They are \\ \cline{1-1} % EMail: !<eMail address>! & distinguished through the \\ \cline{1-1} % Private number: !<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}