如果我定义了一些(许多)键,xkeyval
如果没有明确设置键,我是否真的必须初始化它们才能使用它们?
\documentclass{article}
\usepackage{xkeyval}
\makeatletter
\define@cmdkeys{fam}[my@]{%
fonta,
fontb,
% ...
% fontn
}[]
%\presetkeys{fam}{keya,keyb}{}
%\setkeys{fam}{
% fonta,
% fontb,
% % ...
% % fontn
%}
\newcommand{\mymacro}[2]{%
{\my@fonta #1} and {\my@fontb #2}
}
\makeatother
\begin{document}
\mymacro{Font A}{Font B}
\end{document}
此代码将成为新包的一部分。我的许多键应设置字体,默认情况下该字体为空(ii 如果用户没有为其设置键值对)。我想在宏定义中使用这些字体,但我必须手动将所有字体初始化为空。由于这种行为,我需要在添加新字体时处理两个列表(\define@cmdkeys
和)。\setkeys
据我理解,上述示例应该按原样编译,但我需要取消注释这些\setkeys
行以初始化宏。
当然,有些键必须有预设值,而且我必须初始化它们。例如,我们将是一个预设的savemode
布尔值,但如果用户设置了没有值的键,则应该默认为布尔值。false
true
额外的做什么\presetkeys
?我不明白本节中的手册。最好将其作为新问题发布吗?
答案1
这键值不提供密钥的自动初始化。最好的选择是键盘阅读器和龙腾包;它们提供在定义键之后自动将键初始化为其默认值的命令。键盘阅读器包比龙腾包,但功能较少。下面是基于键盘阅读器(和键值) 包裹。
\documentclass{article}
\usepackage{keyreader}
\usepackage{xcolor}
\makeatletter
\newdimen\shadowsize
\define@boolkey[KV]{shadowbox}[shb@]{frame}[true]{}
\define@boolkey[KV]{shadowbox}[shb@]{shadow}[true]{}
\define@cmdkey[KV]{shadowbox}[shb@]{framecolor}[black]{}
\define@cmdkey[KV]{shadowbox}[shb@]{shadecolor}[white]{}
\define@cmdkey[KV]{shadowbox}[shb@]{shadowcolor}[gray]{}
\define@cmdkey[KV]{shadowbox}[shb@]{boxwidth}[2cm]{}
\define@choicekey+[KV]{shadowbox}{align}[\val\nr]
{center,right,left,justified}[center]{%
\ifcase\nr\relax
\def\curralign##1{\hfil##1\hfil}%
\or
\def\curralign##1{\hfill##1}%
\or
\def\curralign##1{##1\hfill}%
\or
\let\curralign\@iden
\fi
}{%
\@latex@error{Erroneous value for a choice key}
{Invalid value '#1' for key 'align' of family '\XKV@tfam'}%
}
% The following keys could have been defined as command keys, but this is
% just an illustration:
\define@key[KV]{shadowbox}{framesize}{\def\currfboxrule{#1}}
\define@key[KV]{shadowbox}{shadowsize}{\shadowsize=\dimexpr#1\relax}
% Save the values of the following keys when they are being set:
\savevaluekeys[KV]{shadowbox}{frame,framecolor,framesize}
% 'Presetting keys' means set the following keys whenever \setkeys is called.
% These keys should be set BEFORE the keys listed in the current argument of
% \setkeys are set, provided that these keys aren't listed in the current
% argument of \setkeys. If these keys appear in the current argument of \setkeys,
% then obviously the user has new values for them or he wants the keys to be
% set with their default values.
% The command \presetkeys of the xkeyval package expects both 'head' and 'tail'.
% The keyreader package splits \presetkeys into two, hopefully less confusing,
% commands: \krdpresetkeys and \krdpostsetkeys.
\krdpresetkeys[KV]{shadowbox}{%
frame,framecolor=black,framesize=.8pt,boxwidth=2cm,align=center,
shadecolor=gray!15
}
% 'Postsetting keys' means set the following keys whenever \setkeys is called.
% These keys should be set AFTER the keys listed in the current argument of
% \setkeys are set, provided that these keys aren't listed in the current
% argument of \setkeys:
\krdpostsetkeys[KV]{shadowbox}{%
shadow=\usevalue{frame},shadowcolor=\usevalue{framecolor}!40,
shadowsize=\dimexpr\usevalue{framesize}*5\relax
}
\newcommand*\newshadowbox[2][]{%
\krdsetkeys[KV]{shadowbox}{#1}%
\begingroup
\ifshb@frame
\fboxrule=\dimexpr\currfboxrule\relax
\else
\fboxrule=0pt
\fi
\ifshb@shadow\else\shadowsize=0pt \fi
\sbox\z@{\fcolorbox{\shb@framecolor}{\shb@shadecolor}{%
\hb@xt@\shb@boxwidth{\curralign{#2}}%
}}%
\hskip\shadowsize
\color{\shb@shadowcolor}%
\rule[-\dp0]{\wd0}{\dimexpr\ht0+\dp0\relax}%
\llap{\raisebox{\shadowsize}{\box0\hskip\shadowsize}}%
\endgroup
}
\makeatother
\begin{document}
\noindent
\newshadowbox{tobi1}
\newshadowbox[framecolor=gray,shadecolor=blue!25,shadowsize=10pt,align=left]{tobi2}
\newshadowbox[shadow=false,boxwidth=1cm]{tobi3}
\newshadowbox[framesize=2pt,framecolor=red,shadowcolor=green]{tobi4}
\newshadowbox[frame=false,shadow,shadowsize=9pt,shadowcolor=violet!50,align=right]{tobi5}
\end{document}
% Using a feature of the keyreader package, all the above keys can be defined
% compactly as follows. The command \krddefinekeys will automatically initialize
% the keys after they have been defined.
\krddefinekeys*[KV]{shadowbox}[shb@]{%
bool/frame/true;
bool/shadow/true;
cmd/framecolor/black;
cmd/shadecolor/white;
cmd/shadowcolor/gray;
cmd/boxwidth/2cm;
ord/framesize/.5pt/\def\currfboxrule{#1};
ord/shadowsize/2pt/\shadowsize=\dimexpr#1\relax;
choice/align/center/
center.do=\def\curralign##1{\hfil##1\hfil},
right.do=\def\curralign##1{\hfill##1},
left.do=\def\curralign##1{##1\hfill},
justified.do=\let\curralign\@iden;
}