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
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
|
[en]
LaTeX-package 'exp-testopt' - expandable variant of \@testopt
Author: Paul Ebermann <Paul-Ebermann@gmx.de>
License: LPPL 1.3b or later, maintained
(see http://www.latex-project.org/lppl/).
Version: 0.3
All Documentation (other than this file) is in Esperanto.
This package is meant for use by other packages.
This package provides an expandable variant of the LaTeX
kernel command \@testopt, named \@expandable@testopt, and
a more general \@expandable@ifopt, both intended for package
writers. Also we have a variant of \newcommand which
uses these macros to check for optional arguments.
This Package needs no other packages for running.
The typesetting of the documentation needs additionally
class scrartcl (KOMA-script), gmdoc-enhance (from me)
and gmdoc (from Grzegorz `Natror' Murzynowski),
gmdoc's dependencies, and some required LaTeX packages.
The package comes as .dtx + .ins.
Run "tex exp-testopt.ins" to create the style file (and maybe put
it to texmf/tex/latex/paul/, if your docstrip is configured
accordingly), run (after that and maybe updating your TeX hash)
"latex exp-testopt.dtx" to create the documentation.
(Docstrip also creates an exp-testopt.test in the same directory,
which is to be used by the documentation.)
Usage
-------
There are two main commands for package writers:
\@expandable@ifopt{<YES>}{<NO>}
\@expandable@testopt{<COMMAND>}{<DEFAULT>}
Both of them try to check, wether following them is a optional
argument (this is, some stuff enclosed in []). In this case,
they expand to:
<YES>
<COMMAND>
In the other case, they expand to:
<NO>
<COMMAND>[<DEFAULT>]
So, \@expandable@ifopt is a general branch command, while
\@expandable@testopt is meant as a replacement for \@testopt,
where <COMMAND> is "any sequence of commands that 'expects' to
be followed by [." (Quoted from ltdefns.dtx.)
This replacement has the advantage of being expandable
(if <COMMAND> is so), but also has quite some limitations.
A third command is:
\expnewcommand*{<COMMAND>}[<argnum>][<DEFAULT>]{<code>}
This works like \newcommand, but when a command with an
optional argument is defined, it uses our expandable check
for the existence of the optional argument. (Without the default
argument it should work exactly the same.)
Examples
----------
The main usage is in definitions of commands, which are to
accept optional arguments.
\expnewcommand*{\example}[1][Default]{%
\fbox{#1}%
}
Thus \example outputs an box with "Default" in it, while
\example[Test] hat "Test" in it.
From another package (to be published soon):
\expnewcommand*\monthName[2][\languagename]{%
\@format@month@name{#1}{\value{#2}}%
}
This outputs the value of a given LaTeX counter as
a name of the like-numbered month, in the given
language, the default language being the current
babel language. (And here the expansibility is important,
since we don't want the value of the counter when
this is printed, but now, also when this ends up in
the table of contents.)
When you want more control, you may use \@expandable@ifopt{<YES>}{<NO>}:
\def\exampleOne{%
\@expandable@ifopt{%
\exampleOneOpt}{%
\exampleOneNoOpt}%
}
\def\exampleOneOpt[#1]{#2}{
% do something with #1 and #2
}
\def\exampleOneNoOpt#1{%
% do some other thing with #1
}
With \@expandable@testopt{<COMMAND>}{<DEFAULT>} you may also
create commands which accept more than one optional argument.
Benefits
----------
The advantages of \expnewcommand and \@expandable@testopt to
\newcommand and \@testopt are in the expandibility of the created
commands - you can use them in moving arguments (like inside of
\protected@edef, \protected@write and so on), and the accessed variables
then have their current meanings (or the meaning at shipout time, for
write), not the meanings when the thing is finally typeset.
\newcommand, on the other hand, creates protected commands - you can
use them also in moving arguments, but they are evaluated only at
typesetting time.
What to use when depends heavily on the use case.
Limitations
-------------
Since we want to be expandable, we really can't check the next
token, but only the next "macro argument". And comparing also
is not so easy when you can't assign something to a macro.
So, we use as a workaround making a control sequence from the
next argument (trying to neutralize a bit things like control
sequences), and comparing them to a known control sequence.
This has the following consequences:
- we cant distinguish between [ and {[} - the second one
is also regarded as a "start of optional argument".
- the next argument (when it is not simple '[') has to be of a
"friendly" kind - it should not contain braces, and any
"dangerous" token (anything not of category 10, 11, 12)
should come as the first token (only then it is neutralized).
(Often the next argument is only one token, then this is no
problem. Or it will be simple text, also no problem.)
Otherwise, there will be strange errormessages.
- multiple space tokens before the [ may irritate our
macros.
So, before using this macros, make sure the limitations don't
affect you.
Have fun!
-------------
[de]
LaTeX-Paket 'exp-testopt' - Expandierbare Variante von \@testopt.
Autor: Paul Ebermann (Paul-Ebermann@gmx.de).
Lizenz: LPPL 1.3b oder später, mit Maintenance-Status
"author-maintained". Siehe http://www.latex-project.org/lppl/.
Version 0.3
Geschrieben für eigenen Gebrauch
(d.h. für Nutzung in anderen LaTeX-Paketen von Paul Ebermann), aber
vielleicht ist es auch für andere von Nutzen.
Die Dokumentation (außer dieser Datei) ist nur auf Esperanto.
Dieses Paket ist für Verwendung in anderen LaTeX-Paketen gedacht.
Es enthält eine expandierbare Variante des LaTeX-Kernel-Kommandos
\@testopt unter dem Namen \@expandable@testopt, eine
Verallgemeinerung davon als \@expandable@ifopt sowie eine Variante
von \newcommand, welche diese Makros nutzt, um die Existenz
optionaler Argumente festzustellen.
Das Paket kommt als .dtx + .ins.
Mit "latex exp-testopt.ins" wird die .sty-Datei erstellt (und
eventuell gleich nach texmf/tex/latex/paul/ installiert,
wenn docstrip entsprechend eingerichtet ist), mit
"latex exp-testopt.dtx" kann (danach und eventuell nach einer
Aktualisierung der TeX-Dateidatenbank) die Dokumentation neu
erstellt werden.
Docstrip erstellt auch eine Datei exp-testopt.test, welche nur
von der Dokumentation verwendet wird (vom Paket nicht verwendet).
Anwendung
----------
Die beiden Haupt-Kommandos für Package-Autoren:
\@expandable@ifopt{<JA>}{<NEIN>}
\@expandable@testopt{<BEFEHL>}{<DEFAULT>}
Beide versuchen herauszufinden, ob nach ihnen ein optionales
Argument folgt (das ist irgend etwas, was in [...] eingeschlossen
ist). In diesem Fall expandieren diese Makros zu:
<JA>
<BEFEHL>
Im anderen Fall expandieren sie zu:
<NEIN>
<BEFEHL>[<DEFAULT>]
\@expandable@ifopt ist also ein genereller Verzweigungsbefehl,
während \@expandable@testopt (welches dem Paket den Namen gab)
ein Ersatz für \@testopt aus dem LaTeX-Kernes ist: hier sollte
<BEFEHL> eine beliebige Sequenz von Kommandos sein, welche es
'erwartet', von [ gefolgt zu werden. (Frei übersetzt aus
ltdefns.dtx.) Damit kann man Makros mit optionalen Argumenten
und Defaultwerten für diese bauen.
Dieser Ersatz hat den Vorteil, expandierbar zu sein (falls
<BEFEHL> dies ist), hat aber auch einige Beschränkungen (siehe
unten).
Ein drittes Kommando ist:
\expnewcommand*{<MAKRONAME>}[<argnum>][<DEFAULT>]{<Code>}
Es funktioniert analog zu \newcommand, mit dem Unterschied,
dass (falls <DEFAULT> gegeben ist) die Überprüfung auf
optionale Argumente mit unserem \@expandable@testopt anstatt
mit \@testopt (bzw. seiner protected-Variante) geschieht.
(Ohne diesen Default-Wert sollten beide Definitionen exakt
identisch sein.)
Beispiele
-----------
Die Hauptverwendung wird die Definition von Kommandos mit
optionalen Argumenten sein:
\expnewcommand*{\example}[1][Default]{%
\fbox{#1}%
}
Hier gibt \example einen Kasten mit "Default" drin aus, wobei
\example[Test] ein "Test" im Kasten hat.
Aus einem meiner anderen Packages (wird bald veröffentlicht)
sinngemäß:
\expnewcommand*\monthName[2][\languagename]{%
\@format@month@name{#1}{\value{#2}}%
}
Das gibt den Wert eines LaTeX-Zählers in der Form
eines Monatsnamens in der gewählten Sprache aus, wobei
der Default die aktuelle Babel-Sprache ist.
(Hierbei braucht man die Expansibilität wirklich, denn
wir wollen ja den aktuellen Wert des Zählers (und der
Sprache) haben, auch wenn das ganze nachher im
Inhaltsverzeichnis landet, wo eventuell andere Werte
aktuell sind.)
Mehr Kontrolle bekommt man mit \@expandable@ifopt:
\def\exampleOne{%
\@expandable@ifopt{%
\exampleOneOpt}{%
\exampleOneNoOpt}%
}
\def\exampleOneOpt[#1]#2{
% mache etwas mit #1 und #2
}
\def\exampleOneNoOpt#1{%
% mache etwas ganz anderes mit #1
}
Mit \@expandable@testopt kann man auch Kommandos basteln,
welche mehr als ein optionales Argument enthalten.
Vorteile
---------
Die Vorteile von \expnewcommand sowie \@expandable@testopt
im Vergleich zu \newcommand und \@testopt aus dem Kernel liegen
in der Expandierbarkeit der erstellten Kommandos - man kann sie
innerhalb von bewegten Argumenten nutzen (wie \protexted@edef,
\@protected@write etc.) und die darin verwendeten Variablen
haben dann ihre aktuellen Werte, nicht die Werte, wenn der
Text endlich gesetzt wird.
\newcommand (mit den optionalen Argumenten) erstellt "geschützte"
Kommandos - man kann sie in bewegten Argumenten verwenden, aber
sie werden erst dann ausgewertet, wenn sie gesetzt werden.
Welche der beiden Möglichkeiten besser ist, hängt stark von
der jeweiligen Situation ab.
Begrenzungen
--------------
Weil wir expandierbare Makros haben wollen, können wir nicht
wirklich (wie es \@testopt macht) das nächste Token überprüfen,
sondern nur das "nächste Makro-Argument". Der Vergleich ist
auch nicht einfach, wenn man keine Zuweisungen/Definitionen
machen darf.
Als Workaround erstellen wir eine Kontrollsequenz aus dem
nächsten Argument (und versuchen dabei, es etwas unschädlich
zu machen), und vergleichen diese mit einer bekannten
Kontrollsequenz.
Das hat die folgenden Konsequenzen:
- Wir können nicht zwischen [ und {[} unterscheiden - auch
das zweite wird als "Anfang eines optionalen Argumentes"
interpretiert.
- Das nächste Argument (wenn es denn nicht ein einfaches '['
ist) muss sich friedlich verhalten - es sollte keine
{} enthalten, und andere gefährliche Token (alles, was nicht
Kategorie 10, 11, 12 hat) sollten nur an erster Stelle
auftauchen (da können sie unschädlich gemacht werden).
(Wenn das nächste Argument nur aus einem Token besteht,
ist das kein Problem, auch nicht, wenn es einfach nur
Text ist.)
Andernfalls kann es zu merkwürdigen Fehlermeldungen kommen.
- Falls vor dem '[' mehrere Leerzeichen-Token kommen, kann
das unsere Makros verwirren.
Also, bitte vor dem Verwenden dieser Makros aufpassen, dass
die Beschränkungen nicht stören.
Viel Spaß!
----------
[eo]
LaTeX-pakaĵo 'exp-testopt' - plibonigoj por gmdoc.
(Se vi ne scias, kio estas gmdoc, legu sube.)
Aŭtoro: Paŭlo Ebermann (Paul-Ebermann@gmx.de).
Licenzo: LPPL 1.3, 'maintained'
(-> http://www.latex-project.org/lppl/).
Versio 0.3
Kreitaj por propra uzo, sed eble iom de ĝi ankaŭ
uzeblas por aliaj.
La dokumentaro (escepte tiu ĉi dosiero) estas nur en la germana
lingvo.
La pakaĵo ne bezonas ajnajn aliajn pakaĵojn.
Por la dokumentado bezonatas gmdoc, gmdoc-enhance
kaj scrartcl (KOMA-script).
La pakaĵo venas en .dtx + .ins.
Voku "latex exp-testopt.ins" por krei la .sty-dosieron (kaj
eble meti ĝin al texmf/tex/latex/paul/, se via docstrip estis
konfigurita laŭe), voku "latex exp-testopt.dtx" por rekrei
la dokumentaron.
La dokumentaĵo estas en exp-testopt.pdf.
|