1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
|
%% \CheckSum{108}
% \iffalse meta-comment
%
% File: mailmerge.dtx
%
% Copyright (C) 2009 Miguel V. S. Frasson (mvsfrasson@gmail.com)
%
% The LaTeX package mailmerge provides an interface to produce text from
% a template where fields are replaced by actual data, like in a
% database. It is useful to produce several letters from a template,
% certificates or other such documents. It allows to access the entry
% number, number of entries and so on.
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{doc}
\usepackage{amstext,makeidx,ae,mailmerge}
\makeindex
\newcommand{\ttabrechaves}{\char123}
\newcommand{\ttfechachaves}{\char125}
\let\ac\ttabrechaves
\let\fc\ttfechachaves
\begin{document}
\DocInput{mailmerge.dtx}
\end{document}
%</driver>
% \fi
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \StopEventually
%
% \changes{1.0}{2009/09/23}{initial version}
%
% \MakeShortVerb+
%
% \title{\textsf{mailmerge}: repeat amount of text merging fields}
% \author{Miguel Vin\'\i cius Santini Frasson}
% \date{2009--09--23 version 1.0}
%
% \maketitle
%
%
% \tableofcontents
%
% \section{Introduction}
%
% The \LaTeX\ package \textsf{mailmerge} provides an interface to
% produce text from a template where fields are replaced by actual
% data, like in a database. It is useful to produce several letters
% from a template, certificates or other such documents. It allows to
% access the entry number, number of entries and so on.
%
% \section{Usage}
%
% In short, one needs to:
% \begin{enumerate}
% \item declare field names,
% \item define the repetition and
% \item provide entries, each one being a set of values for the fields.
% \end{enumerate}
% It is important to define the repetition with
% \texttt{\string\mailrepeat} \emph{before} provide any entry. We
% present the usage in more detail now.
%
% \begin{enumerate}
% \item \DescribeMacro{\mailfields} Declare the names of the fields,
% with the command \\\mbox{\qquad}
% \texttt{\string\mailfields\ac\textit{name1},\textit{name2},...\fc}\\
% The order declared here is the order in which the values must be
% provided in the parameter of +\mailentry+ (see below.)
%
% \item
% \DescribeMacro{\mailrepeat}
% \DescribeMacro{\field}
% The block of text to be repeated is given as the parameter of
% macro +\mailrepeat+ as in\\\mbox{\qquad}
% \texttt{\string\mailrepeat\ac\textit{...\ text to be
% repeated...\fc}}\\
% Inside the text to be repeated, which can be several paragraphs
% long, each instance of \texttt{\string\field\ac\textit{name}\fc}
% is replaced by the respective value, this for each entry.
%
% \DescribeMacro{\numberoffields} \DescribeMacro{\numberofentries}
% \DescribeMacro{\entrynumber} The command +\numberoffields+ is
% replaced by the number of fields and +\numberofentries+ is
% replaced by the number of entries, but it is necessary two runs to
% update the value. The command +\entrynumber+ is replaced by the
% current entry number. This can be used, for example, in
% determining if current entry has an odd or even number.
%
% For conditional text, depending on field value, one can compare
% value's contents, for example, with the +\ifthenelse+ command
% provided by
% the \textsf{ifthen} package.
%
% \item \DescribeMacro{\mailentry} For each entry, provide a
% command\\\mbox{\qquad}
% \texttt{\string\mailentry\ac\textit{value1},\textit{value2},...\fc}\\
% where \texttt{\textit{value1}} is the value of field named
% \texttt{\textit{name1}}, \texttt{\textit{value2}} is the value of
% field named \texttt{\textit{name2}}, and so on. The values can be
% several paragraphs long. If the value has a comma with it, better
% enclose the value between curly brackets, like in
% \begin{verbatim}
% \mailfields{name,friends,drives}
% \mailentry{John,{Bart,Robert},yes}
% \mailentry{Michael,{Jean,Phillip,Maria},no}
% \end{verbatim}
%
%
% \item \DescribeMacro{\mailnewdata} In case of intention of use of
% several databases in the same file, use the command +\mailnewdata+,
% which resets entries. New uses of +\mailfields+ overhide previous
% field names.
% \end{enumerate}
%
% \section{Example}
%
% \begin{verbatim}
% \usepackage{ifthen,mailmerge}
%
% % \ifequal{A}{B}{what if A=B}{what if A<>B}
% \newcommand{\ifequal}[2]{\ifthenelse{\equal{#1}{#2}}}
%
% \mailfields{name,friends,drives}
%
% \mailrepeat{\section*{\field{name}'s profile}
%
% \field{name} has
% \ifequal{\field{friends}}{}
% {no friends}
% {\field{friends} as friends}.
% \ifequal{\field{drives}}{yes}{Drives.}{Doesn't drive.}
%
% (entry \entrynumber\ of \numberofentries)
%
% % \newpage optional
% }
%
% \mailentry{John,{Bart and Robert},yes}
% \mailentry{Sara,{Jean, Phillip and Maria},no}
% \mailentry{Edward,,yes}
% \end{verbatim}
%
% \noindent what produces the following output:
%
% \newcommand{\ifequal}[2]{\ifthenelse{\equal{#1}{#2}}}
%
% \mailfields{name,friends,drives}
%
% \mailrepeat{\section*{\field{name}'s profile}
%
% \field{name} has
% \ifequal{\field{friends}}{}
% {no friends}
% {\field{friends} as friends}.
% \ifequal{\field{drives}}{yes}{Drives.}{Doesn't drive.}
%
% (entry \entrynumber\ of \numberofentries)
%
% ^^A \newpage optional
% }
%
% \mailentry{John,{Bart and Robert},yes}
% \mailentry{Sara,{Jean, Phillip and Maria},no}
% \mailentry{Edward,,yes}
%
% \section{Idea of implementation}
%
% \begin{itemize}
% \item Each new data initialization (call od +\mailnewdata+) defines
% a tag command with values `a', `aa', `aaa', and so on, saved in
% command +\MAILMcurrtag+.
% \item A +\mailfields+ saves field names to commands +\MAILMfieldI+,
% +\MAILMfieldII+, +\MAILMfieldIII+, etc (ending with upcase roman
% numbers), and at the end, saves in the \texttt{.aux} file the
% number of fields in a command determined by the data tag.
% \item The +\mailrepeat+ command just saves its parameter to a command.
% \item Each \texttt{\string\field\ac\textit{name}\fc} is expanded to
% a command \texttt{\string\MAILMthefield\textit{name}}.
% \item +\numberoffields+ expands to a command whose name is composed
% by \texttt{MAILMnumberfields} plus ``tag''. The same for +\numberofentries+.
% \item Each +\mailentry+ defines the comands
% \texttt{\string\MAILMthefield\textit{nameN}} to expand to
% \texttt{\textit{valueN}}, using
% \texttt{\string\MAILMfield\textit{N-in-roman}} to compose the name
% of the command and expand an entry of the repetition command.
% Now, when the +\field+, +\numberoffields+ and +\numberofentries+
% are expanded, they have ppropriated values.
% \end{itemize}
%
%
% \section{Code}
%
%
% Identidication of the package and use of the package \textsf{ifthen}.
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mailmerge}[2009/09/23 v1.0 repeat amount of text merging fields]
\RequirePackage{ifthen}
% \end{macrocode}
%
% \subsection{(Re)initialization}
%
% Reset counters and update tag command +\MAILMcurrtag+. Inicialize once.
% \begin{macrocode}
\def\MAILMcurrtag{}
\newtoks\MAILMtok
\newcounter{MAILMcount}% aux counter
\newcounter{MAILMentry}%
\newcommand{\mailnewdata}{%
\setcounter{MAILMentry}{0}%
\xdef\MAILMcurrtag{a\MAILMcurrtag}}
\mailnewdata
% \end{macrocode}
%
% \subsection{Saving the repetition in a command}
%
% \DescribeMacro{\mailrepeat}
% \begin{macrocode}
\newcommand{\mailrepeat}[1]{\gdef\MAILMrepetition{#1}}
% \end{macrocode}
%
% \subsection{Restoring data from aux file}
%
% \DescribeMacro{\MAILMsetnumfields}
% \DescribeMacro{\MAILMsetnumentries}
% \DescribeMacro{\numberoffields}
% \DescribeMacro{\numberofentries}
% Commands that extract info from aux file (saved by +\mailfields+ and
% +\mailentry+) and commands that use this information when repeting.
% \begin{macrocode}
\newcommand{\MAILMsetnumfields}[2]
{\expandafter\xdef\csname MAILMnumberoffields#1\endcsname{#2}}
\newcommand{\MAILMsetnumentries}[2]
{\expandafter\xdef\csname MAILMnumberofentries#1\endcsname{#2}}
\newcommand{\numberoffields}
{\csname MAILMnumberoffields\MAILMcurrtag\endcsname}
\newcommand{\numberofentries}
{\csname MAILMnumberofentries\MAILMcurrtag\endcsname}
% \end{macrocode}
%
% \subsection{Saving field names}
%
% \begin{macrocode}
\newcommand{\mailfields}[1]{%
\setcounter{MAILMcount}{0}%
% \end{macrocode}
% \noindent Initiate a loop, where for each entry, the command
% +\MAILMaux+ is set to entry name.
% \begin{macrocode}
\@for\MAILMaux:=#1\do{%
% \end{macrocode}
% \noindent The next line is to extract white space after comma.
% \begin{macrocode}
\edef\MAILMaux{\expandafter\@firstofone\MAILMaux\@empty}%
% \end{macrocode}
% \noindent Define command
% \texttt{\string\MAILMfield\textit{Roman-number}}.
% \begin{macrocode}
\stepcounter{MAILMcount}%
\expandafter\edef\csname MAILMfield\Roman{MAILMcount}\endcsname
{\MAILMaux}%
\edef\numberoffields{\arabic{MAILMcount}}%
}%
% \end{macrocode}
% \noindent Write to \texttt{aux} +\MAILMsetnumfields{tag}{num}+
% \begin{macrocode}
\immediate\write\@mainaux{\string\MAILMsetnumfields
{\MAILMcurrtag}{\theMAILMcount}}%
}
% \end{macrocode}
%
% \subsection{Repeating within an entry}
%
% \DescribeMacro{\field}
% Defining +\field+, that expands to
% \texttt{\string\MAILMthefield\textit{name}}.
% \begin{macrocode}
\newcommand{\field}[1]{\csname MAILMthefield#1\endcsname}
% \end{macrocode}
%
% \DescribeMacro{\mailentry}
% \noindent Each entry increments counter (reset in initialization),
% saves entry number to aux, saves each value to the command expanded
% by +\field+ and expand the repetition, stored in +\MAILMrepetition+.
% The implementation is similar to +\mailfields+.
% \begin{macrocode}
\newcommand{\mailentry}[1]{%
\stepcounter{MAILMentry}%
\edef\entrynumber{\theMAILMentry}%
\immediate\write\@mainaux{\string\MAILMsetnumentries
{\MAILMcurrtag}{\theMAILMentry}}%
\setcounter{MAILMcount}{0}%
\@for\MAILMentryfield:=#1\do{%
\MAILMtok=\expandafter{\MAILMentryfield}%
\stepcounter{MAILMcount}%
\expandafter\long\expandafter\edef
\csname MAILMthefield%
\csname MAILMfield\Roman{MAILMcount}\endcsname
\endcsname {\the\MAILMtok}%
}%
\MAILMrepetition
}
% \end{macrocode}
%
% \Finale \PrintIndex %\PrintChanges
%
%% \CharacterTable
%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%% Digits \0\1\2\3\4\5\6\7\8\9
%% Exclamation \! Double quote \" Hash (number) \#
%% Dollar \$ Percent \% Ampersand \&
%% Acute accent \' Left paren \( Right paren \)
%% Asterisk \* Plus \+ Comma \,
%% Minus \- Point \. Solidus \/
%% Colon \: Semicolon \; Less than \<
%% Equals \= Greater than \> Question mark \?
%% Commercial at \@ Left bracket \[ Backslash \\
%% Right bracket \] Circumflex \^ Underscore \_
%% Grave accent \` Left brace \{ Vertical bar \|
%% Right brace \} Tilde \~}
%
\endinput
|