
Ich habe in letzter Zeit viele Beiträge über den Unterschied zwischen der Verwendung der Schlüssel-Wert-Schnittstelle und der Handler-Schnittstelle von gelesen pgfkeys
. Meines Wissens können auf beide Arten dieselben Werte gespeichert und abgerufen werden. Beispiel:
\documentclass{article}
\usepackage{tikz}
\pgfkeys{
/testa/.initial,
/testb/.store in=\testbvalue,
}
\begin{document}
\def\foo{bar}
\pgfkeys{/testa=\foo,/testb=\foo}
\pgfkeysvalueof{/testa}
\testbvalue
\pgfkeysgetvalue{/testa}\testavalue
\meaning\testavalue
\meaning\testbvalue
\end{document}
Hier kann derselbe Wert durch \pgfkeysvalueof{/testa}
und abgerufen werden \testbvalue
. Tatsächlich ist die Bedeutung von \testavalue
und \testbvalue
dieselbe (was keine Überraschung ist). Aber warum funktioniert dann der folgende Code?
\documentclass{article}
\usepackage{tikz}
\usepackage{etoolbox}
\usepackage{overpic}
\pgfkeys{
/icon/.cd,
width/.initial,
overlay/.store in=\iconoverlay,
set defaults/.unknown/.code={\pgfkeys{/icon/\pgfkeyscurrentname/.default=#1}}
}
\newcommand\icondefaults[1]{%
\pgfkeys{/icon/set defaults/.cd, #1}%
}
\newcommand\ifkeyempty[3]{%
\pgfkeysgetvalue{#1}{\keyvalue}%
\ifempty{\keyvalue}{#2}{#3}%
}
\newcommand\ifempty[3]{%
\def\novalue{\pgfkeysnovalue}%
\def\empty{}%
\ifboolexpr{test {\ifdefequal{#1}{\empty}} or test {\ifdefequal{#1}{\novalue}}}{#2}{#3}%
}
\newcommand{\icon}[2][]{%
{%
\pgfkeys{/icon/.cd,width,overlay,#1}% Reset to default values
\def\options{}%
\ifkeyempty{/icon/width}{}{\edef\options{width=\pgfkeysvalueof{/icon/width},\options}}%
\ifempty{\iconoverlay}{%
\edef\graphic{\noexpand\includegraphics[\options]{#2}}%
}{%
\edef\overlay{\noexpand\begin{overpic}[\options]{#2}}%
\def\graphic{\overlay\put(0,0){\iconoverlay}\end{overpic}}%
}%
\graphic%
}%
}%
\begin{document}
\icondefaults{width=6cm}
\icon{example-image} % Image gets default width 6cm
\icon[width=2cm,overlay={\icon{example-image-overlay}}]{example-image} % Image gets width 2cm, while the overlaid image gets default width 6cm
\icon{example-image} % Image gets default width 6cm
\end{document}
Während der nächste Codeabschnitt nicht funktioniert. Der einzige Unterschied besteht darin, dass /.store in
es nicht für den Schlüssel verwendet wird overlay
und daher \pgfkeysvalueof
zum Zugriff auf den Wert des Schlüssels verwendet wird. Dies führt zu einem Fehler TeX capacity exceeded
.
\documentclass{article}
\usepackage{tikz}
\usepackage{etoolbox}
\usepackage{overpic}
\pgfkeys{
/icon/.cd,
width/.initial,
overlay/.initial,
set defaults/.unknown/.code={\pgfkeys{/icon/\pgfkeyscurrentname/.default=#1}}
}
\newcommand\icondefaults[1]{%
\pgfkeys{/icon/set defaults/.cd, #1}%
}
\newcommand\ifkeyempty[3]{%
\pgfkeysgetvalue{#1}{\keyvalue}%
\ifempty{\keyvalue}{#2}{#3}%
}
\newcommand\ifempty[3]{%
\def\novalue{\pgfkeysnovalue}%
\def\empty{}%
\ifboolexpr{test {\ifdefequal{#1}{\empty}} or test {\ifdefequal{#1}{\novalue}}}{#2}{#3}%
}
\newcommand{\icon}[2][]{%
{%
\pgfkeys{/icon/.cd,width,overlay,#1}% Reset to default values
\def\options{}%
\ifkeyempty{/icon/width}{}{\edef\options{width=\pgfkeysvalueof{/icon/width},\options}}%
\ifkeyempty{/icon/overlay}{%
\edef\graphic{\noexpand\includegraphics[\options]{#2}}%
}{%
\edef\overlay{\noexpand\begin{overpic}[\options]{#2}}%
\def\graphic{\overlay\put(0,0){\pgfkeysvalueof{/icon/overlay}}\end{overpic}}%
}%
\graphic%
}%
}%
\begin{document}
\icondefaults{width=6cm}
\icon{example-image} % Image gets default width 6cm
\icon[width=2cm,overlay={\icon{example-image-overlay}}]{example-image} % Image gets width 2cm, while the overlaid image gets default width 6cm
\icon{example-image} % Image gets default width 6cm
\end{document}
Kann jemand dieses Verhalten erklären? Habe ich das falsch verstanden und denke, dass in beiden Fällen derselbe Wert gespeichert und abgerufen wird, nur auf unterschiedliche Weise?
Antwort1
Sie sind nicht gleichwertig. /.store in
Der Handler führt einfach eine \def
Operation aus und hält den Wert nicht. Durch das Festlegen eines Schlüssels kann jedoch ein Wert abgerufen werden, der in diesem Bereich festgelegt ist. Aus diesem Grund muss im zweiten Fall der Schlüssel festgelegt werden.
Deshalb funktioniert die erste Methode, da die Einstellung auf das Standardverhalten lokal für beide Rekursionsebenen verfügbar ist. Die zweite Methode ändert jedoch den Wert des Schlüssels nicht.
Dazu muss der Overlay-Schlüssel in der Zeile
\pgfkeys{/icon/.cd,width,overlay=,#1}% Notice the equal sign for the overlay key