對 pgfkeys 使用鍵值介面會導致錯誤

對 pgfkeys 使用鍵值介面會導致錯誤

我最近讀了很多關於使用鍵值介面和處理程序介面之間的區別的文章pgfkeys。據我了解,相同的值可以透過兩種方式儲存和檢索。例如:

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

\pgfkeysvalueof{/testa}這裡可以透過和檢索相同的值\testbvalue。事實上\testavalue和的意思\testbvalue是相同的(這並不奇怪)。但是,為什麼下面的程式碼可以工作

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

而下一段程式碼不起作用。唯一的差異是/.store in不用於 key overlay,因此\pgfkeysvalueof用於存取 key 的值。它會導致錯誤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}

誰能解釋這種行為?我的理解是否錯誤,在兩種情況下都儲存和檢索相同的值,只是以不同的方式?

答案1

它們並不等同。/.store inhandler 只是執行一個\def操作,並不會儲存該值。然而,設定一個鍵允許人們檢索在該範圍內設定的值。這就是為什麼在第二種情況下必須設定密鑰。

這就是第一個起作用的原因,因為預設行為的設定對於兩個遞歸等級都可以在本地使用。然而,第二個不會改變鍵的值。

為此,您必須在該行中明確地將覆蓋鍵設為空

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

相關內容