setkeys 的参数

setkeys 的参数

我的动机基于包listings(也是我的包mdframed)。该包允许通过定义样式\lstset{foo}{options}。现在我想创建一个宏来扩展样式foo。例如\Apptolstset{foo}{more options}

我创建了以下示例。

\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{testpackage.sty}
\ProvidesPackage{testpackage}
\RequirePackage{etoolbox,kvoptions}
\SetupKeyvalOptions{family=test,prefix=test@}
\DeclareStringOption[\bfseries]{font}
\DeclareStringOption[\normalsize]{size}
\ProcessKeyvalOptions*\relax
\newcommand\testsetup{\setkeys{test}}

\define@key{test}{loadstyle}{%
  \ifcsundef{test@style@#1}{}%
        {\expandafter\testsetup\expandafter{\csname test@style@#1\endcsname}}%
}
\newrobustcmd*\teststyle[2]{%
  \csdef{test@style@#1}{#2}%
}

\newrobustcmd*\apptodefinestyle[2]{%
 \ifcsundef{test@style@#1}%
   {}%
   {\csappto{test@style@#1}{,#2}}%
}


\newrobustcmd*\testresult[1]{{\test@font\test@size #1}}
\end{filecontents}
\usepackage{testpackage}
\begin{document}
Hello World!
\testresult{Hello World!}

\teststyle{new}{font=\bfseries\itshape}
\apptodefinestyle{new}{size=\Large}
\testsetup{loadstyle=new}

\testresult{Hello World!}

\end{document}

本例的错误之处在于:

! Missing \endcsname inserted.
<to be read again>
\protect
l.35 \testsetup{loadstyle=new}
The control sequence marked <to be read again> should
not appear between \csname and \endcsname.

如果我使用组合

\define@key{test}{loadstyle}{%
  \ifcsundef{test@style@#1}{}%
        {\csuse{test@style@#1}}%
}
\newrobustcmd*\teststyle[2]{%
  \csdef{test@style@#1}{\testsetup{#2}}%
}

一切都会正常。但是对于这种组合,我不知道如何定义\apptoteststyle应该扩展当前样式的命令。

我希望问题清楚了。

答案1

\setkeys不会扩展其第二个参数。如果您有一个包含键的宏,则需要先将其扩展。请注意,这\csuse会增加一个扩展步骤(就像任何宏一样),因此您应该使用底层\csname ... \endcsname。这必须扩展两次,一次根据其名称创建宏,然后扩展宏本身。

所以:

\expandafter\expandafter\expandafter
\testsetup\expandafter\expandafter
\expandafter{\csname test@style@#1\endcsname}

相关内容