Hier wurde eine ähnliche Frage schon gestellt, mit folgendem Beispiel. Open in writeLaTeX
\documentclass{article} \newcommand{\name}[3][Herr]{\textbf{#1}~\textsc{#2}~\textit{#3}} \begin{document} \name[Frau]{Maria}{Musterfrau} \name{Max}{Mustermann} \end{document} Nachteil dieser Art von Befehlsdefinition ist unter anderem, dass man sich Art und Reihenfolge der Argumente merken muss. Könnte man den gezeigten Befehl auch so definieren, dass die Argumente in folgender Form übergeben werden? Open in writeLaTeX
\name[anrede=Herr,nachname=Mustermann,vorname=Max] |
Eine weitere Methode ist das Paket Open in writeLaTeX
\define@key{<Familie>}{<Key>}[<Leerwert>]{<Code>} Und wird in dieser Form auch von Open in writeLaTeX
\define@key[<Präfix>]{<Familie>}{<Key>}[<Leerwert>]{<Code>} Setzen kann man sie dann später mit Open in writeLaTeX
\setkeys{<Familie>}{<Keys>} Das folgende Beispiel bastelt mein Beispiel aus der Antwort mit Open in writeLaTeX
\documentclass{article} \usepackage{keyval} \makeatletter \newcommand*\name@anrede{Herr/Frau} \newcommand*\name@vorname{Vorname} \newcommand*\name@nachname{Nachname} \define@key{name}{anrede} {\renewcommand*\name@anrede{#1}} \define@key{name}{vorname} {\renewcommand*\name@vorname{#1}} \define@key{name}{nachname}{\renewcommand*\name@nachname{#1}} \newcommand*\name[1][]{% \begingroup \setkeys{name}{#1}% \name@anrede\ \name@vorname\ \name@nachname \endgroup } \makeatother \begin{document} \name\par \name[anrede=Frau,nachname=Musterfrau,vorname=Mia]\par \name \end{document} Mit Open in writeLaTeX
\define@cmdkey[<Präfix>]{<Familie>}[<Befehl-Präfix>]{<Name>}{<Code>} Das definierte Makro bekommt den Namen Open in writeLaTeX
\documentclass{article} \usepackage{xkeyval} \makeatletter \newcommand*\name@anrede{Herr/Frau} \newcommand*\name@vorname{Vorname} \newcommand*\name@nachname{Nachname} \define@cmdkey{name}[name@]{anrede} {} \define@cmdkey{name}[name@]{vorname} {} \define@cmdkey{name}[name@]{nachname}{} \newcommand*\name[1][]{% \begingroup \setkeys{name}{#1}% \name@anrede\ \name@vorname\ \name@nachname \endgroup } \makeatother \begin{document} \name\par \name[anrede=Frau,nachname=Musterfrau,vorname=Mia]\par \name \end{document} Definiert man die Makros vorher nicht selber, so kann man bei beiden Methoden durch Testen, ob das entsprechende Makro existiert, auch auf einfache Weise Fehlermeldungen oder anderes Verhalten etc. erreichen: Open in writeLaTeX
\documentclass{article} \usepackage{xkeyval} \makeatletter \define@cmdkey{name}[name@]{anrede} {} \define@cmdkey{name}[name@]{vorname} {} \define@cmdkey{name}[name@]{nachname}{} \newcommand*\name[1][]{% \begingroup \setkeys{name}{#1}% \@ifundefined{name@anrede} {Herr/Frau} {\name@anrede} \@ifundefined{name@vorname} {Vorname} {\name@vorname} \@ifundefined{name@nachname} {Nachname} {\name@nachname}% \endgroup } \makeatother \begin{document} \name\par \name[anrede=Frau,nachname=Musterfrau,vorname=Mia]\par \name \end{document} beantwortet 12 Aug '14, 21:30 cgnieder |
Hinweis: diese Antwort stammt eigentlich aus der Originalfrage http://texwelt.de/wissen/fragen/8404/ist-es-moglich-eigene-befehle-mit-mehr-als-einem-optionalen-argument-zu-definieren. Ich poste sie hier in einer modifizierten Kopie, damit wir die Knowledge-Base leichter lesbar haben. Ich schlage folgende Variante mit Open in writeLaTeX
\documentclass{article} \usepackage{pgfkeys} \pgfkeys{ % dies DEKLARIERT keys mit dem angegebenen initial wert. % der suffix '/.initial' heisst "legen neuen Key mit dem % angegeben Wert an". /feynman/anrede/.initial=, /feynman/name/.initial=, /feynman/vorname/.initial=, } \newcommand{\name}[1]{% \begingroup % Dies nimmt die key-value-liste #1 und setzt alle keys. % Wenn jemand "anrede" schreibt, wird automatisch "/feynman/" % davor gehaengt: \pgfqkeys{/feynman}{#1}% % % hier hoelen wir Werte ab und speichern sie in Makros: \pgfkeysgetvalue{/feynman/anrede}\feynmanAnrede \pgfkeysgetvalue{/feynman/name}\feynmanName \pgfkeysgetvalue{/feynman/vorname}\feynmanVorname % % Nun kann man was damit machen - z.B. mithilfe von TeX % Programmierung: \ifx\feynmanAnrede\empty \else \textbf{\feynmanAnrede}~% \fi % \ifx\feynmanVorname\empty \PackageError{feynman}{Vorname fehlt}{}% \else \textsc{\feynmanVorname}~% \fi % \textit{\feynmanName}% \endgroup } \begin{document} \name{anrede=Frau, vorname=Maria, name=Musterfrau}% \name{vorname=Max, name=Mustermann} \end{document} Diese Variante unterscheidet sich von der anderen hier vorgestellten dadurch, dass sie die Werte "direkt" in den Key speichert anstelle noch ein extra-makro zu verwenden. Vorteil (neben vernachlaessigbaren Speichereinsparungen): man kann dann auch sowas wie Details zu dem Stichwort "TeX Programmierung" habe ich mal zusammengeschrieben, man findet das - zusammen mit weiterfuehrenden Hinweisen zu beantwortet 16 Aug '14, 10:43 cfeuersaenger |
Das KOMA-Script Paket Dazu muss man zunächst eine Schlüssel-Familie definieren Open in writeLaTeX
\DefineFamily{<Familie>} und das aktuelle Paket (hier: das Dokument) dieser Familie zuweisen: Open in writeLaTeX
\DefineFamilyMember{<Familie>} Danach kann man mit Open in writeLaTeX
\DefineFamilyKey{<Familie>}{<Schlüssel>}{<Code>} Schlüssel-Optionen definieren. Ausgeführt werden die Optionen dann mit Open in writeLaTeX
\FamilyExecuteOptions{<Famlilie>}{<Keys>} Genauer beschrieben ist das im Das folgende Beispiel bastelt das Beispiel aus meiner Antwort mit Open in writeLaTeX
\documentclass{scrartcl} % \usepackage{scrbase}% ohne KOMA-Script-Klasse benötigt \makeatletter \newcommand*\name@anrede{Herr/Frau} \newcommand*\name@vorname{Vorname} \newcommand*\name@nachname{Nachname} \DefineFamily{name} \DefineFamilyMember{name} \DefineFamilyKey{name}{anrede} {\renewcommand*\name@anrede{#1}} \DefineFamilyKey{name}{vorname} {\renewcommand*\name@vorname{#1}} \DefineFamilyKey{name}{nachname}{\renewcommand*\name@nachname{#1}} \newcommand*\name[1][]{% \begingroup \FamilyExecuteOptions{name}{#1}% \name@anrede\ \name@vorname\ \name@nachname \endgroup } \makeatother \begin{document} \name\par \name[anrede=Frau,nachname=Musterfrau,vorname=Mia]\par \name \end{document} beantwortet 13 Aug '14, 15:44 cgnieder |
Eine Möglichkeit ist es, das Paket Open in writeLaTeX
\documentclass{article} \usepackage{pgfkeys} \makeatletter \pgfkeys{ name/.cd ,% Pfad eindeutig für Befehl machen anrede/.code = \renewcommand*\name@anrede{#1} , vorname/.code = \renewcommand*\name@vorname{#1} , nachname/.code = \renewcommand*\name@nachname{#1} , } \newcommand*\name@anrede{Herr/Frau} \newcommand*\name@vorname{Vorname} \newcommand*\name@nachname{Nachname} \newcommand*\name[1][]{% \begingroup \pgfqkeys{/name}{#1}% \name@anrede\ \name@vorname\ \name@nachname \endgroup } \makeatother \begin{document} \name\par \name[anrede=Frau,nachname=Musterfrau,vorname=Mia]\par \name \end{document} Das Beispiel definiert Keys, die alle zum Pfad Jeder Key muss mit einem Handler definiert werden. Der einfachste ist Im Befehl am Schluss werden die Keys schließlich gesetzt. Dabei ist beantwortet 12 Aug '14, 20:38 cgnieder Für
(12 Aug '14, 20:57)
Henri
@Henri :) kannte ich noch nicht. (Ich nutze
(12 Aug '14, 21:00)
cgnieder
Ich hätte allerdings trotzdem
(12 Aug '14, 21:01)
cgnieder
@Clemens Ich finde es so wie es ist wunderbar :) So haben wir beide was gelernt.
(12 Aug '14, 21:04)
Henri
1
@cfeuersaenger hat hier noch einen weiteren Vorschlag mit
(15 Aug '14, 23:11)
esdd
Danke @esdd. Irgendwie scheint sich meine Antwort auf die urspruengliche Frage mit der Entscheidung, eine separate Frage zu keyval zu stellen, ueberschnitten zu haben :-( Vielleicht kopiere ich die hierhin; da findet man sie besser.
(16 Aug '14, 10:35)
cfeuersaenger
Ergebnis 5 von 6
show 1 more comments
|
Ein Ansatz mit
Open in writeLaTeX
\documentclass{article} \usepackage{xparse} \ExplSyntaxOn \tl_new:N \l_feynman_anrede_tl \tl_new:N \l_feynman_vorname_tl \tl_new:N \l_feynman_nachname_tl \keys_define:nn { feynman } { anrede .tl_set:N = \l_feynman_anrede_tl, anrede .initial:n = {Herr}, vorname .tl_set:N = \l_feynman_vorname_tl, nachname .tl_set:N = \l_feynman_nachname_tl, } \msg_new:nnnn { feynman } { feld-fehlt } { #1 ~ fehlt } { Das ~ Feld ~ #1 ~ muss ~ einen ~ Wert ~ haben } \cs_new_protected:Npn \feynman_name:n #1 { \group_begin: \keys_set:nn { feynman } { #1 } \tl_if_empty:NT \l_feynman_vorname_tl { \msg_error:nnn { feynman } { feld-fehlt } { vorname } } \tl_if_empty:NT \l_feynman_nachname_tl { \msg_error:nnn { feynman } { feld-fehlt } { nachname } } \textbf{\l_feynman_anrede_tl}~ \textsc{\l_feynman_vorname_tl}~ \textit{\l_feynman_nachname_tl} \group_end: } \NewDocumentCommand\name{ m }{ \feynman_name:n { #1 } } \ExplSyntaxOff \begin{document} \name{nachname=Mustermann,vorname=Max} \name{anrede=Herr,vorname=John,nachname=Doe} \end{document} beantwortet 12 Aug '14, 20:32 Henri Vielleicht kannst Du beschreiben, wo man Nachlesen kann, was Du da in dieser seltsamen Schreibweise machst ;) Am besten noch: gleich selber beschreiben
(12 Aug '14, 20:41)
cgnieder
|
Neben den bereits genannten gibt es u. a. auch noch
kvsetkeys
undkvoptions
. Ich habe beide bisher nicht verwendet, weshalb ich auch keine Beispiele dafür erstellen kann. Siehe auch das CTAN-Topickeyval
.