我认为keyval
宏的参数应该限制在其宏范围内,但是以下代码:
\documentclass{report}
\usepackage{xkeyval}
% Define a custom command option using `boolkey`
\makeatletter
\define@boolkey{myCommand}[]{option}[true]{} % one boolean option
\newcommand{\myCommand}[2][]{%
\setkeys{myCommand}{#1}%
\ifoption%
\textbf{#2}%
\else%
#2%
\fi%
}
\makeatother
\begin{document}
\myCommand{not bold} % default behaviour is not to bold
\myCommand[option]{bold} % explicitly set option to bold
\myCommand{not bold} % fail! default behaviour was expected!
\myCommand[option=false]{not bold} % workaround that makes the "default" concept useless
\end{document}
生成:
为什么?我是不是漏掉了什么?
有没有办法让这个默认行为不管之前是否调用过宏都可以正常工作?
答案1
宏定义本身不会添加分组级别,因此您在宏代码中所做的一切都会“泄漏”并且只发生在调用宏的范围内。这个想法是,调用定义\somemacro
与\newcommand
在该位置粘贴代码参数的内容相同(没有周围的括号)。
例如
\documentclass{article}
\usepackage{xcolor}
\newcommand*{\mygreen}[1]{%
\color{green}#1}
\begin{document}
Not green
{\mygreen{this is green}
but so is this...}
again black
\end{document}
产生两行绿色文本,因为\mygreen
没有范围限制,不会阻止它应用于下一行。最后一行超出了调用的范围\mygreen
,所以它又是黑色的。
简单的解决方案是添加\begingroup...\endgroup
以使您的设置本地化到宏调用。
\documentclass{report}
\usepackage{xkeyval}
% Define a custom command option using `boolkey`
\makeatletter
\define@boolkey{myCommand}[]{option}[true]{} % one boolean option
\newcommand{\myCommand}[2][]{%
\begingroup
\setkeys{myCommand}{#1}%
\ifoption%
\textbf{#2}%
\else%
#2%
\fi%
\endgroup
}
\makeatother
\begin{document}
\myCommand{not bold} % default behaviour is not to bold
\myCommand[option]{bold} % explicitly set option to bold
\myCommand{not bold} % fail! default behaviour was expected!
\myCommand[option=false]{not bold} % workaround that makes the "default" concept useless
\end{document}