[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.

