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
|
% \iffalse meta-comment
% Line endings: UNIX
% Tab size: 4
%
% Copyright 2004 Jonathan Sauer
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%
% http://www.latex-project.org/lppl.txt
%
% and version 1.3 or later is part of all distributions of LaTeX
% version 2003/12/01 or later.
%
% This work has the LPPL maintenance status "maintained".
%
% The Current Maintainer of this work is Jonathan Sauer
% (<jonathan.sauer@gmx.de>).
%
% This work consists of the files optparams.dtx and optparams.ins
% and the derived file optparams.sty.
%
% \fi
%
% \iffalse
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{optparams}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
% Modification of verbatim for tabs in listings
\makeatletter
{\catcode`\ =\active%
\catcode`\^^I=\active%
\gdef\@vobeyspaces{%
\catcode`\ \active\let \@xobeysp%
\catcode`\^^I\active\def^^I{~~}%
}}%
\makeatother
\begin{document}
\DocInput{\jobname.dtx}
\end{document}
%</driver>
%
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{optparams}
%<package> [2004/08/14 v0.9 multiple optional parameters in macros]
%
% \fi
%
% \CheckSum{12}
% \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 \~}
%
% \DoNotIndex{\@ifnextchar,\@nil,\def,\newcommand}
%
% \GetFileInfo{\jobname.sty}
%
% \title{The \textsf{optparams} package\thanks{This document
% corresponds to \textsf{\filename}~\fileversion, dated \filedate. The
% package is based on David Kastrup's macros for `Around the Bend
% 21'.}}
%
% \author{Jonathan Sauer \\ \texttt{jonathan.sauer@gmx.de}}
%
% \date{\filedate}
%
% \maketitle
%
% \begin{abstract}
% This file describes the \textsf{optparams} package that provides a
% small macro for creating macros with multiple optional parameters.
%
% \end{abstract}
%
% \tableofcontents
%
%
%
% \section{Introduction}
%
% The \LaTeX\ macro |\newcommand| is used to define macros that may
% have one optional parameter (the first one). However, there is no
% easy way of defining macros having several optional parameters. This
% package provides the macro |\optparams| to simplify the creation of
% macros with multiple optional parameters (or optional parameters
% only).
%
%
%
% \section{Examples}
%
% \subsection{Example one}
%
% \begin{verbatim}
% \long\def\test@[#1][#2][#3][#4]{%
% (#1) (#2) (#3) (#4)
% }
%
% \newcommand{\test}{%
% \optparams{\test@}{[one][two][three][four]}%
% }
% \end{verbatim}
% You have now defined a macro |\test| that takes up to four optional
% parameters (|#1| to |#4|). You can call this macro as:
%
% \begin{itemize}
% \item |\test[this]|, resulting in |(this) (two) (three) (four)|.
%
% \item |\test[this][is]|, resulting in |(this) (is) (three) (four)|.
%
% \item |\test[this][is][a]|, resulting in |(this) (is) (a) (four)|.
%
% \item |\test[this][is][a][test]|, resulting in |(this) (is) (a) (test)|.
%
% \end{itemize}
% You see that the default parameters defined in |\test| are replaced
% one by one by the parameters given when |\test| is called.
%
%
%
% \subsection{Example two}
%
% \begin{verbatim}
% \long\def\test@[#1][#2][#3][#4]#5{%
% (#1) (#2) (#3) (#4) !#5!
% }
%
% \newcommand{\test}{%
% \optparams{\test@}{[one][two][three][four]}%
% }
% \end{verbatim}
% You have now defined a macro |\test| that takes up to four optional
% parameters (|#1| to |#4|) and one mandatory parameter (|#5)|. You
% can call this macro as:
%
% \begin{itemize}
% \item |\test[this]{foo}|, resulting in
% |(this) (two) (three) (four) !foo!|.
%
% \item |\test[this][is]{foo}|, resulting in
% |(this) (is) (three) (four) !foo!|.
%
% \item |\test[this][is][a]{foo}|, resulting in
% |(this) (is) (a) (four) !foo!|.
%
% \item |\test[this][is][a][test]{foo}|, resulting in
% |(this) (is) (a) (test) !foo!|.
%
% \end{itemize}
%
%
%
% \section{Description of the macros}
%
% \DescribeMacro{\optparams} Usage: |\optparams| \marg{macro}
% \marg{default parameters}.
%
% This macro reads any optional parameters from the input and finally
% calls your macro with the optional parameters as well as the
% remaining default parameters.
%
% Each default parameter must have the form |[|\meta{value}|]|. As all
% default parameters are passed as one parameter to |\optparams|, they
% must be enclosed in braces (|{|\meta{default parameters}|}|).
%
% The macro that is finally called must have as many optional
% parameters as have been defined in the call of |\optparams|; their
% form must be |[|\meta{parameter}|]|, where \meta{parameter} is a
% number beginning with one and ending with nine.\footnote{This is a
% general restriction of \TeX: A macro cannot have more than nine
% parameters.} The parameter numbers must be numbered consecutively,
% i.e. |[#1][#2][#3]| instead of |[#1][#2][#4]|.
%
% Because of this special way of declaring macro parameters, you
% cannot use |\newcommand| but have to use the \TeX\ primitiv |\def|.
% As |\def|, contrary to |\newcommand|, does not warn you when you
% overwrite an already existing macro, you first should define the
% macro as a dummy using |\newcommand| and then correctly using
% |\def|, i.e.:
%
% \begin{verbatim}
% \newcommand{\test@}{}
% \long\def\test@[#1][#2][#3][#4]{%
% <macro>
% }
% \end{verbatim}
% This way you do not accidentally overwrite an existing macro.
%
% What does the |\long| do? In \TeX, in order to quicker capture
% errors such as missing right braces |}|, parameters of macros
% defined using |\def| cannot contain a |\par|, or \TeX\ will complain
% (`runaway argument?'). This makes it easier for the user to spot
% mistakes, as in that case \TeX\ will stop processing immediately at
% the end of the current paragraph and not continue until i.e. the end
% of the file before realizing that a macro parameter has not been
% closed via |}|.
%
% But there is a way to make the usage of |\par| as a macro parameter
% possible: Using |\long| in front of the |\def|. In \LaTeX,
% |\newcommand| defines macros as |\long| by default, and its variant
% |\newcommand*| defines macros restricted to `short' parameters. So
% as demonstrated in the examples, you should either use |\newcommand|
% and |\long\def| together or |\newcommand*| and |\def| in order to
% make your macros behave correctly.
%
%
%
% \section{Notes}
%
% \begin{itemize}
% \item If you use the notation used in the examples above,
% \meta{macroname} for the main macro and
% \meta{macroname}|@| for the macro finally called by
% |\optparams|, and if you define these macros not in a
% package or class, but in your document preamble, you have
% to enclose the definitions in |\makeatletter| \ldots\
% |\makeatother|, otherwise you cannot use |@| in macro
% names.
%
% \item If you define a macro having only optional parameters (as
% in the first example above), you have to make sure the
% macro is not called in a context where a |[| follows not
% as a parameter, but simply as an opening bracket, i.e.
% |\test[foo] [as a side note| \ldots, where the call of
% |\test| should have only |[foo]| as its only
% parameter. In this case |\optparams| will think that
% another optional parameter follows, resulting in chaos.
%
% To prevent this from happening, insert a |\relax| after
% the last optional parameter of the macro call, i.e.
% |\test[foo]\relax [as a side note| \ldots\ Then
% |\optparams| will stop looking for more optional
% parameters.
%
% \end{itemize}
%
% \StopEventually{}
%
%
%
% \section{Implementation}
%
% \subsection{Main macros}
%
% \begin{macro}{\optparams}
%
% Calls |#1| using a variable number of parameters. Default parameters
% are provided in |#2| in the form |[|\meta{param one}|]| |[|\meta{param
% two}|]| \ldots
%
% \begin{macrocode}
\newcommand{\optparams}[2]{%
\optparams@{#1}{}{#2}%
}
% \end{macrocode}
% \end{macro}
%
%
%
% \subsection{Internal macros}
%
% \begin{macro}{\optparams@}
%
% Checks if the next character from the input is a |[|. If true calls
% |\optparams@@|, as there are still optional parameters left. Otherwise
% calls \meta{macro} with \meta{parameters read} and \meta{remaining
% default parameters}.
%
% Usage: |\optparams@| \marg{macro} \marg{parameters read}
% \marg{remaining default parameters}.
%
% \begin{macrocode}
\def\optparams@#1#2#3{%
\@ifnextchar[{%
\optparams@@{#1}{#2}#3\@nil%
}{%
#1#2#3%
}%
}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\optparams@@}
%
% Reads the next optional parameter from the input (as |#5| or
% \meta{new parameter}). Then gobbles up the corresponding default
% parameter (as |#3| or \meta{default for parameter read}, appends the
% parameter read to \meta{parameters read} and calls |\optparams@|
% again to check for more optional parameters.
%
% Usage: |\optparams@@| \marg{macro} \marg{parameters read}
% \marg{default for parameter read} \marg{remaining default
% parameters} \marg{new parameter}.
%
% \begin{macrocode}
\def\optparams@@#1#2[#3]#4\@nil[#5]{%
\optparams@{#1}{#2[#5]}{#4}%
}
% \end{macrocode}
% \end{macro}
%
% Now this is quite a coincidence: Thirteen lines of code, and this
% package was begun on Friday, 13th \ldots
%
% \Finale
% \PrintChanges
% \PrintIndex
\endinput
|