El uso de la interfaz clave-valor para pgfkeys produce un error

El uso de la interfaz clave-valor para pgfkeys produce un error

He estado leyendo muchas publicaciones últimamente sobre la diferencia entre usar la interfaz clave-valor y la interfaz del controlador de pgfkeys. Según tengo entendido, los mismos valores se pueden almacenar y recuperar de ambas maneras. Por ejemplo:

\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}

Aquí se puede recuperar el mismo valor mediante \pgfkeysvalueof{/testa}y \testbvalue. De hecho, el significado de \testavaluey \testbvaluees el mismo (lo cual no sorprende). Pero entonces, ¿por qué funciona el siguiente código?

\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}

Mientras que la siguiente sección del código no funciona. La única diferencia es que /.store inno se usa para la clave overlayy, por lo tanto, \pgfkeysvalueofse usa para acceder al valor de la clave. Resulta en un error 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}

¿Alguien puede explicar este comportamiento? ¿Tengo entendido mal que se almacena y recupera el mismo valor en ambos casos, solo que de diferentes maneras?

Respuesta1

No son equivalentes. /.store inEl controlador simplemente realiza una \defoperación y no retiene el valor. Sin embargo, establecer una clave permite recuperar un valor establecido en ese alcance. Por eso en el segundo caso hay que configurar la clave.

Es por eso que el primero funciona porque la configuración del comportamiento predeterminado está disponible localmente para ambos niveles de recursividad. Sin embargo, el segundo no cambia el valor de la clave.

Para eso, debes establecer explícitamente la clave de superposición en nada en la línea

\pgfkeys{/icon/.cd,width,overlay=,#1}% Notice the equal sign for the overlay key

información relacionada