我正在尝试使用该xkeyval
包在新环境中包含关键参数。除了默认值外,它似乎有效。这是我迄今为止最好的尝试:
\documentclass{article}
\usepackage{xkeyval}
\makeatletter
\define@key{Mystuff}{foo}[what]{\def\foo{#1}}
\define@key{Mystuff}{bar}[whatever]{\def\bar{#1}}
\savekeys{Mystuff}{foo,bar}
\makeatother
\newenvironment{myenv}[1][]%
{\setkeys{Mystuff}{#1}BEGIN \foo}
{END \bar}
\begin{document}
\begin{myenv}[bar=BAAAR]
Uh?
\end{myenv}
\end{document}
但这会导致 LaTeX 抱怨
\foo
未定义:
! Undefined control sequence.
\\myenv [#1]->\setkeys {Mystuff}{#1}BEGIN \foo
l.18 \begin{myenv}[bar=BAAAR]
输出将类似于“ BEGIN Uh? END BAAAR
”(没有默认的“what”值\foo
)。
我做错了什么,我怎样才能改变这个例子以便\foo
使用默认值?
答案1
当你指定键但不分配值时,将使用默认值:\begin{myenv}[foo]
将定义\foo
为what
。说
\newenvironment{myenv}[1][]%
{\setkeys{Mystuff}{foo,bar,#1}BEGIN \foo}
{END \bar}
以便应用默认值。
或者说
\define@key{Mystuff}{foo}{\def\foo{#1}}
\define@key{Mystuff}{bar}{\def\bar{#1}}
和
\newenvironment{myenv}[1][]%
{\setkeys{Mystuff}{foo=what,bar=whatever,#1}BEGIN \foo}
{END \bar}
关键是绝不如果未指定,则进行评估\setkeys
。
实际上,正如 Ulrike Fischer 和 Ahmed Musa 指出的那样,人们可以“预设”一些键,这相当于在列表中指定它们\setkeys
:
\define@key{Mystuff}[what]{foo}{\def\foo{#1}}
\define@key{Mystuff}[whatever]{bar}{\def\bar{#1}}
\presetkeys{Mystuff}{foo,bar}{}
采用什么策略主要取决于应用程序。如果你总是需要foo
并且bar
设置,那么\presetkeys
更经济,因为在指定键时不会执行两次分配。
但是\presetkeys
,也可以在环境定义中进行,因此环境定义可以是
\newenvironment{myenv}[1][]%
{\presetkeys{foo,bar}{}%
\setkeys{Mystuff}{#1}BEGIN \foo}
{END \bar}
并且这不会影响使用这些Mystuff
密钥的其他环境。
答案2
\savekeys
是错误的命令。你想要的是
\presetkeys{Mystuff}{foo,bar}{}
然后该密钥foo
将被插入到列表的开头\setkeys
。