
Ich habe etwa fünf Stunden (!) damit verbracht, zu lernenWie erstelle ich einen Befehl mit Schlüsselwerten?(und andere Ressourcen) und versuche zu verstehen, wie man Schlüsselwerte implementiert, und es war äußerst verwirrend. Ich habe einen im Wesentlichen trivialen (jedenfalls für die meisten Leute hier) Testfall geschrieben und es gibt einige Inkonsistenzen, die ich nicht erklären kann.
Hier ist ein MWE, das verwendet keyval
.
% !TEX TS-program = lualatexmk
% !TEX encoding = UTF-8 Unicode
\documentclass{article}
\usepackage{keyval}
\makeatletter
% Key definitions
\define@key{sayhello}{towhom}{\def\sh@towhom{#1}}
% Key defaults
\setkeys{sayhello}{towhom=Michael}
% Define the command that uses the key
\newcommand{\sayhello}[2][]{%
%\begingroup% localizes the new settings w/o calling the defaults
\setkeys{sayhello}{towhom=Michael} % Reset defaults w/o localizing
\setkeys{sayhello}{#1} % Set new keys
Say hello to \sh@towhom\ #2.
%\endgroup%
}%
\makeatother
\begin{document}
\sayhello{tomorrow}
%\sayhello[towhom]{today} % throws no value specified for towhom
\sayhello[towhom=Jill]{tomorrow}
%\sayhello[towhom]{today} % throws no value specified for towhom
\sayhello[towhom=Joe]{tomorrow}
%\sayhello[towhom]{tomorrow} % throws no value specified for towhom
\sayhello{today}
\end{document}
Und hier ist ein MWE, das verwendet pgfkeys
.
% !TEX TS-program = lualatexmk
% !TEX encoding = UTF-8 Unicode
\documentclass{article}
\usepackage{pgfkeys}
\pgfkeys{%
/sayhello/.is family, /sayhello,
towhom/.default=Michael,
towhom/.store in=\sayto
}%
\newcommand*{\sayhello}[2][]{%
\pgfkeys{/sayhello,#1}
Say hello to \sayto\ #2.
}%
\begin{document}
%\sayhello{tomorrow} % throws undefined control sequence
\sayhello[towhom]{today}
\sayhello[towhom=Jill]{tomorrow}
\sayhello[towhom]{today}
\sayhello[towhom=Joe]{tomorrow}
\sayhello[towhom]{tomorrow}
\sayhello{today} % works perfectly
\end{document}
Ich hatte gehofft, dass beide Implementierungen identische Ergebnisse liefern würden. Das tun sie aber nicht. keyval
scheint die Angabe eines Schlüssels ohne Wert nicht zu mögen. pgfkeys
verhält sich inkonsistent, wenn überhaupt keine Optionen angegeben sind, verhält sich aber perfekt, wenn dies keyval
nicht der Fall ist. Sind meine Beispiele falsch codiert? Sind die Inkonsistenzen das erwartete Verhalten? Ich bin völlig verwirrt.
Antwort1
Sie verwechseln den Anfangswert und den Standardwert. Der zweite wird verwendet, wenn Sie einen Schlüssel verwenden, ohne einen Wert anzugeben. Wenn Sie außerdem einen Befehl zum Speichern eines Schlüsselwerts verwenden, ist es eine gute Praxis, ihn zuerst mit zu definieren \newcommand
, da Sie so vermeiden, dass Sie vorhandene Befehle überschreiben.
Ich persönlich finde pgfkeys
es verwirrender, da dabei derselbe Befehl zum Definieren und Setzen von Schlüsseln verwendet wird und das Verständnis des Verhaltens einiger Handler nicht immer einfach ist, siehe z. B.Was machen die pgfkeys-Schlüsselhandler .get und .store?.
\documentclass{article}
\usepackage{keyval}
\makeatletter
\newcommand\sh@towhom{}
\define@key{sayhello}{towhom}[Default]{\def\sh@towhom{#1}}
\setkeys{sayhello}{towhom=Initial}
\newcommand{\sayhello}[2][]{%
\begingroup
\setkeys{sayhello}{#1} % Set new keys
keyval, say hello to \sh@towhom\ #2.
\endgroup%
}%
\makeatother
\usepackage{pgfkeys}
\newcommand\sayto{}
\pgfkeys{%
/sayhello/.is family, /sayhello,
towhom/.store in=\sayto,
towhom/.default=Default,
towhom = Initial,
}%
\newcommand*{\sayhellopgf}[2][]{%
\begingroup
\pgfkeys{/sayhello,#1}%
pgfkeys, say hello to \sayto\ #2.
\endgroup
}%
\ExplSyntaxOn
\tl_new:N \l_sayhello_towhom_tl
\keys_define:nn {sayhello}
{
towhom .tl_set:N = \l_sayhello_towhom_tl,
towhom .initial:n = Initial,
towhom .default:n = Default
}
\NewDocumentCommand\sayhelloexpl{O{}m}
{
\group_begin:
\keys_set:nn{sayhello}{#1}
l3keys,~say~hello~to~\l_sayhello_towhom_tl\c_space_tl#2
\group_end:
}
\ExplSyntaxOff
\begin{document}
\sayhello{tomorrow}
\sayhello[towhom]{today}
\sayhello[towhom=Jill]{tomorrow}
\sayhello[towhom]{today}
\sayhello[towhom=Joe]{tomorrow}
\sayhello[towhom]{tomorrow}
\sayhello{today}
\sayhellopgf{tomorrow}
\sayhellopgf[towhom]{today}
\sayhellopgf[towhom=Jill]{tomorrow}
\sayhellopgf[towhom]{today}
\sayhellopgf[towhom=Joe]{tomorrow}
\sayhellopgf[towhom]{tomorrow}
\sayhellopgf{today}
\sayhelloexpl{tomorrow}
\sayhelloexpl[towhom]{today}
\sayhelloexpl[towhom=Jill]{tomorrow}
\sayhelloexpl[towhom]{today}
\sayhelloexpl[towhom=Joe]{tomorrow}
\sayhelloexpl[towhom]{tomorrow}
\sayhelloexpl{today}
\end{document}