具有有效集合中离散选择的条件的规范宏定义

具有有效集合中离散选择的条件的规范宏定义

定义宏的规范方法是什么(大概现在首选 xparse),它根据一组离散选择之一采取不同的行为。

\mymacro[a]{does one thing, e.g., print this in red}
\mymacro[b]{does another thing, e.g., print this in footnotesize}
\mymacro[c]{yet something else, e.g., shows a dagger}
\mymacro[uuu]{throw a latex error, because uuu is undefined}

我自己已经写过几次了(用ifthenelse),但我不知道我是否破坏了意图。有没有规范的方法?

答案1

您可以使用\str_case

\documentclass{article}
\usepackage{color}
\ExplSyntaxOn
\cs_new:Npn\tmp_case:n#1{
\str_case:nnF{#1}{
 {}{nothing}
{a}{does~one~thing,~e.g.,~print~this~in~\textcolor{red}{red}}
{b}{does~another~thing,~e.g.,~print~this~in~{\footnotesize footnotesize}}
{c}{yet~something~else,~e.g.,~shows~a~dagger~$\dagger$}
}
{\PackageError{tmp}{bad~string:~#1}{}}
}


\NewDocumentCommand\mymacro{O{}}% why optional?
{\tmp_case:n{#1}}

\ExplSyntaxOff
\begin{document}

\mymacro

\mymacro[a]

\mymacro[uuu]

\end{document}

这使

! Package tmp Error: bad string: uuu.

See the tmp package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              
                                                  
l.25 \mymacro[uuu]
                  
?

在此处输入图片描述

答案2

\ifcase在我的评论中,我建议在选项以整数替代形式提供时使用。但是,如果您坚持使用字符串选项...

我不确定你的问题是否有一个规范的答案,因为你在 MWE 中指定的结果不符合模式……例如“显示匕首”没有使用提供的参数,而“用红色打印”则使用了。

因此我制定了一种方法,基本上要求你定义所有行动就单个参数宏而言。此类操作通常不需要参数,但您必须创建一个需要参数的宏。

基本上,\setoption[<option name>]{<action>}用于定义的语法行动s(如上所述,行动负责吸收提供给 的主要参数\mymacro。 调用是通过 完成的\mymacro[<option name>]{<argument>}

\documentclass{article}
\usepackage{xcolor}
\def\setoption#1#2{\expandafter\def\csname option#1\endcsname{#2}}
\newcommand\mymacro[1][undefined]{\ifcsname option#1\endcsname
    \def\next{\csname option#1\endcsname}%
  \else
    \def\next{\setundef{#1}}%
  \fi
  \next
}
\setoption{a}{\textcolor{red}}
\setoption{b}{\setfootsize}
\setoption{c}{\setdag}
\newcommand\setfootsize[1]{{\footnotesize#1}}
\newcommand\setdag[1]{$\dag$}% #1 discarded
\newcommand\setundef[2]{Undefined option: #1}% #2 discarded
\begin{document}
\mymacro[a]{does one thing, e.g., print this in red}

\mymacro[b]{does another thing, e.g., print this in footnotesize}

\mymacro[c]{yet something else, e.g., shows a dagger}

\mymacro[uuu]{throw a latex error, because uuu is undefined}
\end{document}

在此处输入图片描述

答案3

一定不是with \ifthenelse:如果选择过多,则嵌套变得无法进行:

\newcommand{\mymacro}[1][]{%
  \ifthenelse{\equal{#1}{}}{nothing}{%
    \ifthenelse{\equal{#1}{a}}{\textcolor{red}{Something}}{%
      \ifthenelse{\equal{#1}{b}}{{\footnotesize something}}{%
        \ifthenelse{\equal{#1}{c}}{\textdagger}{%
          \ERROR
        }%
      }%
    }%
  }%
}

(我甚至不想尝试看看它是否正确)。

可能的替代方法

\documentclass{article}
\usepackage{xcolor}
\makeatletter
\newcommand{\defineswitchmacro}[2]{%
  \@ifdefinable{#1}{%
    \newcommand#1[1][]{%
      \@ifundefined{\string#1@##1}{\ERROR}{\@nameuse{\string#1@##1}}%
    }%
    \defineswitchmacro@{#1}#2\relax\relax
  }%
}
\newcommand{\defineswitchmacro@}[3]{%
  \ifx#2\relax
    \expandafter\@gobble
  \else
    \@namedef{\string#1@#2}{#3}
    \expandafter\@firstofone
  \fi
    {\defineswitchmacro@{#1}}%
}
\makeatother

\defineswitchmacro{\mymacro}{
  {}{nothing}
  {a}{\textcolor{red}{Something}}
  {b}{{\footnotesize Something}}
  {c}{\textdagger}
}

\begin{document}

\mymacro\par
\mymacro[a]\par
\mymacro[b]\par
\mymacro[c]\par
\mymacro[uuu]

\end{document}

使用比所获更有意义的错误消息\ERROR

更现代的方法

\documentclass{article}
\usepackage{xcolor}

\ExplSyntaxOn

\NewDocumentCommand{\defineswitchmacro}{mm}
 {% #1 = macro to define
  % #2 = cases
  \NewDocumentCommand{#1}{O{}}
   {
    \str_case:nnF { ##1 } { #2 } { \ERROR }
   }
 }

\ExplSyntaxOff

\defineswitchmacro{\mymacro}{
  {}{nothing}
  {a}{\textcolor{red}{Something}}
  {b}{{\footnotesize Something}}
  {c}{\textdagger}
}

\begin{document}

\mymacro\par
\mymacro[a]\par
\mymacro[b]\par
\mymacro[c]\par
\mymacro[uuu]

\end{document}

在此处输入图片描述

相关内容