Können keyval und pgfkeys identische Ergebnisse erzeugen?

Können keyval und pgfkeys identische Ergebnisse erzeugen?

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. keyvalscheint die Angabe eines Schlüssels ohne Wert nicht zu mögen. pgfkeysverhält sich inkonsistent, wenn überhaupt keine Optionen angegeben sind, verhält sich aber perfekt, wenn dies keyvalnicht 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 pgfkeyses 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}

Bildbeschreibung hier eingeben

verwandte Informationen