summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/cweb/src/keyvald.dtx
blob: 6873fde711070bdcafbd0dbf43a8d9b19ee0183e (plain)
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
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
%% $ITI: keyvald.dtx,v 1.2 1995/08/25 19:00:31 schrod Exp $
%%------------------------------------------------------------
%% (history at end)
%
% \iffalse
%% File: keyvald.dtx; changed version of
%% File: keyval.dtx Copyright (C) 1993-1994 David Carlisle
%
%<*dtx>
          \ProvidesFile{keyvald.dtx}
%</dtx>
%<*!plain>
%<package&!plain>\NeedsTeXFormat{LaTeX2e}
%<package&!plain>\ProvidesPackage{keyvald}
%<driver>        \ProvidesFile{keyvald.drv}
% \fi
%                \ProvidesFile{keyvald.dtx}
                 [1994/08/23 v1.08.1 key=value parser (DPC) w/ defaults (js)]
%
% \iffalse
%</!plain>
%<*driver>
\documentclass{ltxdoc}
\usepackage{keyvald}
\begin{document}
 \DocInput{keyvald.dtx}
\end{document}
%</driver>
% \fi
%
% \GetFileInfo{keyvald.dtx}
% \title{The \textsf{keyvald} package\thanks{This file
%        has version number \fileversion, last
%        revised \filedate.}}
% \author{David Carlisle\\carlisle@cs.man.ac.uk
%       \and
%       changed by\\Joachim Schrod\\
%       \texttt{<schrod@iti.informatik.th-darmstadt.de>}
%       }
% \date{\filedate}
% \maketitle
%
% \begin{abstract}
%  A \LaTeX\ package implementing a system allowing the setting
%  of parameters (or `named arguments' with a
%  \meta{key}${}={}$\meta{value} syntax.
%
%  Eg: |\foo[height=3in, shadow = true ]{bar}|
% \end{abstract}
%
% \CheckSum{110}
%
% \changes{v1.03}
%         {1993/10/13}{Initial version}
% \changes{v1.04}{1993/11/15}
%         {Upgrade after comments from Timothy van Zandt}
% \changes{v1.05}{1993/11/17}
%         {Further small improvements}
% \changes{v1.06}{1994/02/01}
%         {Update to LaTeX2e}
% \changes{v1.07}{1994/03/15}
%         {New style ltxdoc}
% \changes{v1.08}{1994/09/12}
%         {Improve docstrip handling}
% \changes{v1.08.1}{1995/08/23}
%         {Default keys}
%
%
% This package implements a system of defining and using sets of
% parameters, which are set using the syntax \meta{key}=\meta{value}.
%
% For each keyword in such a set, there exists a function which is
% called whenever the parameter appears in a parameter list. For
% instance if the set |dpc| is to have the keyword |scale| then I
% would define.\\
% | \define@key{dpc}{scale}{scale ({\tt\string#1})\\}|\\
% The first argument of |\define@key| is the  set of keywords being
% used, the second is the keyword, and the third is the function to
% call. This function will be given as |#1| the \meta{value} specified
% by the user.
%
% Normally it is an error to omit the `=\meta{value}' however if an
% optional \meta{value} is supplied when the keyword is defined, then
% just the keyword need be supplied.\\
% |\define@key{dpc}{clip}[true]{...}|\\
% For `|clip|' you can go `|clip = true|' or `|clip = false|' or
% just `|clip|', which is the same as `|clip = true|'
%
% To use these keywords, just call `|\setkeys|' with a comma
% separated list of settings, each of the form
% \meta{key}=\meta{value}, or just \meta{key}. Any white space around
% the `|=|' and `|,|' is ignored.
%
% As the \meta{key} is passed as a macro argument, if it consists
% entirely of a |{ }| group, the outer  braces are stripped off. Thus
% |,key=foo,| and |key=,{foo},| are equivalent. This fact enables one to
% `hide' any commas or equals signs that must appear in the value. i.e.\
% in |foo={1,2,3},bar=4|, |foo| gets the value |1,2,3|, the comma after
% |1| does not terminate the keyval pair, as it is `hidden' by the
% braces.
%
% Empty entries, with nothing between the commas, are silently ignored.
% This means that it is not an error to have a comma after the last
% term, or before the first.
%
% \section{Example}
%
% We may extend the examples above to give  a `fake' graphics
% inclusion macro, with a syntax similar to that used in the psfig
% macros.
%
% \makeatletter
% \def\dpcgraphics{\@ifnextchar[\@dpcgraphics{\@dpcgraphics[]}}
%
% |\dpcgraphics| has one optional argument which is passed through
% |\setkeys|, and one mandatory argument, the filename. It actually
% just typesets its arguments, for demonstration.
%
% \def\@dpcgraphics[#1]#2{{\setkeys{dpc}{#1}INPUT: #2}}%
%
% \define@key{dpc}{scale}{scale ({\tt\string#1\relax})\\}
% \define@key{dpc}{height}{height ({\tt#1})\\}
% \define@key{dpc}{width}{width ({\tt#1})\\}
% \define@key{dpc}{bb}{bounding box ({\tt#1})\\}
% \define@key{dpc}{clip}[true]{clip ({\tt\string#1\relax})\\}
% \makeatother
%
% The declared keys are: |scale|, |height|, |width|, |bb|,
% and |clip|. Except for the last, they must all be given a value if
% used.
%
% Note how in the following, any white space arround |=| or |,| is
% ignored, as are the `empty' arguments caused by extra commas. Note
% also that each macro receives {\em exactly\/} the tokens that you
% specify as arguments, no premature expansion is done.
%
% \begin{verbatim}
% \def\dpcgraphics{\@ifnextchar[\@dpcgraphics{\@dpcgraphics[]}}
% \def\@dpcgraphics[#1]#2{{\setkeys{dpc}{#1}INPUT: #2}}
%
% \define@key{dpc}{scale}{scale ({\tt\string#1\relax})\\}
% \define@key{dpc}{clip}[true]{clip ({\tt\string#1\relax})\\}
% \end{verbatim}
%
% \begin{minipage}{.4\textwidth}
% \begin{verbatim}
% \def\scalemacro{9}
% \dpcgraphics
% [ height =4in, ,
%   width = 3in,
%   scale = \scalemacro,
%   bb = 20 20 300 400 ,
%   clip,
%  ]{aaa}
% \end{verbatim}
% \end{minipage}
% \hfill
% \begin{minipage}{.4\textwidth}
% \def\scalemacro{9}
%\dpcgraphics
% [ height =4in, ,
%   width = 3in,
%   scale = \scalemacro ,
%   bb = 20 20 300 400 ,
%   clip ,
%  ]{aaa}
% \end{minipage}
%
%
% \section{The Internal Interface}
% A declaration of the form:\\
% |\define@key{family}{key}{...}|\\
% Defines a macro |\KV@prefix@key| with one argument. When used in a
% keyval list, the macro receives the value as its argument.
%
% A declaration of the form:\\
% |\define@key{family}{key}[default]{...}|\\
% Defines a macro |\KV@family@key| as above, however it also defines the
% macro |\KV@family@key@default| as a macro with no arguments, and
% definition\\
%  |\KV@family@key{default}|.
%
% Thus if macros are defined using |\define@key|, the use of a key with
% no value \ldots|,foo,|\ldots\ is always equivalent to the use of the
% key with some value, \ldots|,foo=default,|\ldots. However a package
% writer may wish that the `default' behaviour for some key is not
% directly equivalent to using that key with a value. (In particular, as
% pointed out to me by Timothy Van Zandt, you may wish to omit error
% checking on the default value as you know it is correct.) In these
% cases one simply needs to define the two macros
% |\KV@|\meta{family}|@key| and |\KV@|\meta{family}|@key@default|
% directly using |\def| (or |\newcommand|). I do not supply a user
% interface for this type of definition, but it is supported in the
% sense that I will try to ensure that any future upgrades of this
% package do not break styles making use of these `low level'
% definitions.
%
% \StopEventually{}
%
% \section{The Macros}
%
% From version~1.05, all `internal' macros associated to keys have names
% of the form:\\
% |\KV@|\meta{family}|@|\meta{key} or
% |\KV@|\meta{family}|@|\meta{key}|@|\meta{default}
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
% \begin{macro}{\setkeys}
% The top level macro. |#2| should be a comma separated values of the
% form  \meta{key} |=| \meta{value} or just simply \meta{key}.
% The macro associated with this key in the `family' |#1| is called with
% argument \meta{value}. The second form is only allowed if the key was
% declared with a default value.
%    \begin{macrocode}
\def\setkeys#1#2{%
%    \end{macrocode}
%  Save the `family' for later. Then begin acting on the comma
%  separated list.
%    \begin{macrocode}
  \def\KV@prefix{KV@#1@}%
  \KV@do#2,\relax,}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\KV@do}
% Iterate down the list of comma separated argument pairs.
%    \begin{macrocode}
\def\KV@do#1,{%
 \ifx\relax#1\empty\else
  \KV@split#1==\relax
  \expandafter\KV@do\fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\KV@split}
% Split up the keyword and value, and call the appropriate command.
% This macro was slightly reorganised for version 1.04, after some
% suggestions from Timothy Van Zandt.
%    \begin{macrocode}
\def\KV@split#1=#2=#3\relax{%
  \KV@@sp@def\KV@key{#1}%
  \ifx\KV@key\@empty\else
    \expandafter\let\expandafter\@tempc
      \csname\KV@prefix\KV@key\endcsname
    \ifx \@tempc\relax
      \expandafter\let \expandafter\@tempc
        \csname\KV@prefix*\endcsname
      \def\@tempa{*}%
    \else
      \let\@tempa\KV@key
    \fi
    \ifx\@tempc\relax
      \KV@err{\KV@key\space undefined}%
    \else
      \ifx\@empty#3\@empty
        \KV@default
      \else
        \KV@@sp@def\@tempb{#2}%
        \expandafter\@tempc\expandafter{\@tempb}\relax
      \fi
    \fi
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\KV@default}
% Run the default code, or raise an error.
%    \begin{macrocode}
\def\KV@default{%
  \expandafter\let\expandafter\@tempb
    \csname\KV@prefix\@tempa @default\endcsname
  \ifx\@tempb\relax
    \KV@err{No value specified for \KV@key}%
  \else
    \@tempb\relax
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\KV@err}
% Error messages.
%    \begin{macrocode}
\def\KV@err#1{\PackageError{keyvald}{#1}{}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\KV@@sp@def}
% \begin{macro}{\KV@@sp@b}
% \begin{macro}{\KV@@sp@c}
% |\KV@@sp@def|\meta{cmd}\meta{token list} is like |\def|, except that
% a space token at the beginning or end of \meta{token list} is
% removed before making the assignment. \meta{token list} may not
% contain the token |\@nil|, unless it is within a brace group.
% The names of these commands were changed at version~1.05 to ensure
% that they do not clash with `internal' macros in a key family `sp'.
%
% The following three lines are equivalent to\\
% |\def\KV@@sp@def#1#2{\KV@@sp@b#2\@nil\@nil~\@nil\relax#1}|\\
% Where |~| is an explicit space token.
%    \begin{macrocode}
\def\@tempa#1{%
\def\KV@@sp@def##1##2{\KV@@sp@b##2\@nil\@nil#1\@nil\relax##1}}
\@tempa{ }
\def\KV@@sp@b#1#2 \@nil{\KV@@sp@c#1#2}
\def\KV@@sp@c#1\@nil#2\relax#3{\def#3{#1}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\define@key}
% Define the command associated to the key |#2| in the family |#1|.
% First looks for a default argument (the default value for the
% key)
%    \begin{macrocode}
\def\define@key#1#2{%
  \@ifnextchar[{\KV@def{#1}{#2}}{\@namedef{KV@#1@#2}####1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\KV@def}
% Make the definitions of the command, and the default value.
%    \begin{macrocode}
\def\KV@def#1#2[#3]{%
  \@namedef{KV@#1@#2@default\expandafter}\expandafter
    {\csname KV@#1@#2\endcsname{#3}}%
  \@namedef{KV@#1@#2}##1}
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
% \Finale
%
\endinput

%------------------------------------------------------------
%
% $ITIlog: keyvald.dtx,v $
% Revision 1.2  1995/08/25  19:00:31  schrod
%     Add enhanced version of keyval package, with ability to specify
% default action for unknown keyword options.
%