Die Verwendung der Schlüssel-Wert-Schnittstelle für pgfkeys führt zu einem Fehler

Die Verwendung der Schlüssel-Wert-Schnittstelle für pgfkeys führt zu einem Fehler

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 \testavalueund \testbvaluedieselbe (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 ines nicht für den Schlüssel verwendet wird overlayund daher \pgfkeysvalueofzum 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 inDer Handler führt einfach eine \defOperation 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

verwandte Informationen