pgfkeys“.estore in”处理程序未按预期工作

pgfkeys“.estore in”处理程序未按预期工作

在从 (x)keyval 迁移到 pgfkeys 的过程中,我意识到.estore in没有正确扩展我的命令。

这是我的最小工作示例:

\documentclass{report}

\usepackage{pgfkeys}
\makeatletter

\newif\if@wgetdoc@title@ownpage
\pgfkeys{
    /wgetdoc/title/.cd,
    maintitle/.estore in=\@wgetdoc@title@maintitle,
    subtitle/.estore in=\@wgetdoc@title@subtitle,
    author/.estore in=\@wgetdoc@title@author,
    filename/.estore in=\@wgetdoc@title@filename,
    ownpage/.is if=@wgetdoc@title@ownpage
}

\renewcommand{\title}[1][]{%

    \pgfqkeys{/wgetdoc/title}{#1}

    \@ifundefined{@wgetdoc@title@filename}{

        \@ifundefined{@wgetdoc@title@maintitle}{
            \ClassError{wgetdoc}{You did not specify a main title}{}
        }{}

        \@ifundefined{@wgetdoc@title@maintitle}{
            \ClassError{wgetdoc}{You did not specify a main title}{}
        }{}

        \ifx\@wgetdoc@title@maintitle\@empty
            \ClassError{wgetdoc}{The main title you specified is empty}{}
        \fi

        % Custom horizontale rule only local to this environment
        \newcommand{\@wgetdoc@title@hrule}{\rule{\linewidth}{1mm}}

        \if@wgetdoc@title@ownpage
            \begin{titlepage}
                \begin{center}

                    \@wgetdoc@title@hrule%
                    \vspace{0.4cm}

                    {\Huge\textbf{\@wgetdoc@title@maintitle}\par}%

                    \vspace{0.4cm}%
                    \@wgetdoc@title@hrule

                    \@ifundefined{@wgetdoc@title@subtitle}{}{
                        \vspace{1.5cm}
                        {\Large{\@wgetdoc@title@subtitle}\par}%
                    }

                    \@ifundefined{@wgetdoc@title@author}{}{
                        \vspace*{\fill}
                        {\emph{\GetTranslation{author}: \@wgetdoc@title@author}\par}%
                    }

                \end{center}
            \end{titlepage}%
        \else
            \begin{center}
                {\huge\textbf{\@wgetdoc@title@maintitle}\par}
                \@ifundefined{@wgetdoc@title@subtitle}{}{
                    {\large{\@wgetdoc@title@subtitle}\par}%
                }
            \end{center}
            \@ifundefined{@wgetdoc@title@author}{}{
                {\emph{\GetTranslation{author}: \@wgetdoc@title@author}\par}%
            }
            \@wgetdoc@title@hrule%
        \fi

    }{
        \IfFileExists{\@wgetdoc@title@filename}{%
            \includepdf[pages={1}]{\@wgetdoc@title@filename}%
            \ClassInfo{wgetdoc}{\@wgetdoc@title@filename has been used as title page. Any other argument have been discarded.}{}
        }{%
            \ClassError{wgetdoc}{You specified \@wgetdoc@title@filename as filename for the page title, but it could not be found.}{}
        }
    }
}

\makeatother

\begin{document}

\title[maintitle=hello world, ownpage, subtitle=hello world]

Hello world

\end{document}

我一删除格式,就输入

\title[maintitle=hello world, ownpage, subtitle=hello world]

代替

\title[maintitle=hello world, ownpage, subtitle=hello \textsc{world}]

这是可行的。有人能向我解释一下为什么estore in它没有按预期工作吗(在分配值之前扩展它)。这在使用时可以正常工作xkeyval

我尝试编译(使用)时收到的错误xelatex

! Use of \\title doesn't match its definition.
\text@command #1->\def \reserved@a {
                                    #1}\ifx \reserved@a \@empty \let \check@...
l.88 ...d, ownpage, subtitle=hello \textsc{world}]

?

答案1

.estore in处理程序适用于值可能依赖于宏的情况,该宏可能在设置和使用所创建的宏时接收不同的值。此类宏对于完全扩展应该是安全的。

事实上,人们必须意识到.estore in使用\edef和几个排版宏无法存活的事实:\textsc是其中之一,连同所有字体选择宏。

maintitle/.store in=\@wgetdoc@title@maintitle,你做的时候

maintitle=Hello world,

你只需表演

\def\@wgetdoc@title@maintitle{Hello world}

并且您不需要扩展;当\@wgetdoc@title@maintitle使用时,它将扩展为Hello world

pgfkeys如果也提供一个处理程序就好了.protectedestore in,至少在 LaTeX 环境中是这样;可惜,没有这样的东西,而且无论如何你也不需要它。


我会避免代码中的所有空行,并更加小心地保护行尾。

答案2

\textsc(以及许多其他文本格式化宏)无法扩展,导致无法及时处理,这通常被称为早期扩展。这才是问题所在。

如果您需要在宏存储之前进行扩展,则可以使用/.expand once/.expand twice/.expanded处理程序,并使用store in

另外还有一个错误报告等待修复/.estore in

答案3

根据@egreg 的回答。

因此,为了解决这个问题,我只需要使用.store in而不是.estore in。这真的很奇怪,因为.estore in只是为了确保正确扩展内容(参见pgfkeys 文档)。但在我的用例中,即使不需要使用,\url或也能够正确扩展。\textsc.estore in

如果有人发表评论并解释原因。

相关内容