注意回答 OP 关于预设键的问题

注意回答 OP 关于预设键的问题

我很难创建一个可以接受多个选项的宏。我想创建的是\mycommand[up,middle]{Macro}输出Macro with 'up' and 'middle' specified。使用etoolbox下面的 MWE,我可以输出单个选项,以及在没有给出任何选项或给出无效选项时输出。但我不知道如何输出多个选项。

我不需要使用etoolbox,但我很喜欢这个语法。David Carlisle 建议使用类似的语法\newcommand\foo[2][]{\@for\tmp:=#1\do{.... something with \tmp and #2...}},但我不知道如何将其应用于我的示例。

\documentclass{article}
\usepackage{etoolbox}

\newrobustcmd{\mycommand}[2][]{%
 \ifstrequal{#1}{up}{% option up
   #2 with `up' specified
   }{% option middle
   \ifstrequal{#1}{middle}{%
    #2 with `middle' specified
    }{% nothing specified
    \ifstrempty{#1}{%
     #2 with nothing specified
     }{% something specified
     #2 is invalid
   }{\relax}%
  }{\relax}%
 }%
}%

\begin{document}

\mycommand[up]{Macro}

\mycommand[middle]{Macro}

\mycommand[]{Macro}

\mycommand[bla]{Macro}

\end{document}

在此处输入图片描述

答案1

使用的建议\@for可能会产生类似的效果

\documentclass{article}

\usepackage{etoolbox}
\makeatletter
\newrobustcmd{\mycommand}[2][]{% first the options that are equal for all
  \@for\tmp:=#1\do{%
    \expandafter\ifstrequal\expandafter{\tmp}{up}
      {'up' seen}%
      {%
        \expandafter\ifstrequal\expandafter{\tmp}{middle}
          {'middle' seen}
          {%
            \expandafter\ifstrempty\expandafter{\tmp}
              {}
              {INVALID}%
          }%
      }%
  }%
}%
\makeatother

\begin{document}

\mycommand[up]{Macro}

\mycommand[middle]{Macro}

\mycommand[]{Macro}

\mycommand[bla]{Macro}


\end{document}

由于我不知道您想要什么“有效载荷”,我只是排版了所看到的信息:在实际情况下,这可能会用于设置开关或宏以便在参数\do完成后使用。

答案2

您可以尝试其中一个 keyval 包,例如xkeyval

\documentclass{article}
\usepackage{xkeyval}
\makeatletter
\define@choicekey+{myKeys}{foo}[\val\nr]{up,middle}{%
  \ifcase\nr\relax
      \def\keyval{up}       \or
      \def\keyval{middle}   
  \fi}{\def\keyval{\{not defined\}}} 
\makeatother

\newcommand\mycommand[2][]{%
  \ifx\relax#1\relax\def\keyval{\{empty\}} 
  \else\setkeys{myKeys}{#1}\fi
  we do something which depends to \keyval
}%

\begin{document}

\mycommand[foo=up]{Macro}

\mycommand[foo=middle]{Macro}

\mycommand[]{Macro}

\mycommand[foo=bla]{Macro}

\end{document}

在此处输入图片描述

答案3

这是另一个解决方案:

\documentclass{article}
\usepackage{keyreader}
\usepackage{xcolor}
\makeatletter
\krddefinekeys[JKV]{jorg}[jorg@]{%
  choice/key1/a+x/{
      a+x.do=\def\currcolor{blue},
      a+y.do=\def\currcolor{green},
      b+x.do=\def\currcolor{red},
      b+y.do=\def\currcolor{magenta}
    }
    /\def\val{Value of key1: #1}
  ;
  choice/align/justified/{
      center.do=\def\curralign{center},
      right.do=\def\curralign{flushright},
      left.do=\def\curralign{flushleft},
      justified.do=\def\curralign{@justified},
    }
  ;
}
\krdpresetkeys[JKV]{jorg}{key1=a+x,align=justified}
\def\@justified{}
\def\end@justified{}

% Tests:
\newcommand\jorgcommand[2][]{%
  \krdsetkeys[JKV]{jorg}{#1}%
  \endgraf\bigskip\noindent\textbf{\val}\endgraf
  \begin{\curralign}%
  \removelastskip
  \textcolor{\currcolor}{#2}%
  \end{\curralign}%
}
\makeatother

\begin{document}
\def\atext{%
  \texttt{choice} keys of pre-version~0.5 of \texttt{keyreader} package will always check 
  their values against the state pattern and raise an error if 
  there is no match. So you don't have to specify a fallback error message.
}

\jorgcommand[key1=a+x,align=justified]{\atext}
\jorgcommand[key1=a+y,align=center]{\atext}
\jorgcommand[key1=b+x,align=right]{\atext}
\jorgcommand[key1=b+y,align=left]{\atext}
\jorgcommand{\atext}
% Invalid value for key1 ('x+y' not allowed):
% \jorgcommand[key1=x+y]{\atext}
\end{document}

在此处输入图片描述

注意回答 OP 关于预设键的问题

在我上面的例子中,你会发现调用\jorgcommand{\atext}。这没有调用可选参数,因此参数#1为空\jorgcommand。因此,在这种情况下\jorgcommand使用即时键的值

\krdpresetkeys[JKV]{jorg}{key1=a+x,align=justified}

如果我们使用

\newcommand\jorgcommand[2][]{%
  \if\relax\detokenize{#1}\relax\else
    \krdsetkeys[JKV]{jorg}{#1}%
  \fi
  ...#2...
}

正如 Herbert 所建议的,不会调用预设的键值。因此,我们可能会无意中应用键的最新值,这不是预期或正确的步骤。仅在\setkeys\krdsetkeys实例化时才会设置预设键。

相关内容