在从 (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
如果有人发表评论并解释原因。