switch-case条件

switch-case条件

子句只有两个\ifthenelse——<then clause> 和 <clause>,如果需要两个以上的测试条件,就\ifthenelse需要嵌套,这样代码就比较难维护了。有没有更好的办法,比如像这样的 switch-case 宏(类似 C 语言):

\switchconditon
  {<case 1> <clause 1>}
  {<case 2> <clause 2>}
  {<case 3> <clause 3>}

例如\ifthenelse

\ifthenelse{\equal{#1}{ul}}%ul=upper left
        {\let\position\AtPageUpperLeft}
        {}
    \ifthenelse{\equal{#1}{ll}}%ll=lower left
        {\let\position\AtPageLowerLeft}
        {}
    \ifthenelse{\equal{#1}{pc}}%pc=paper center
        {\let\position\AtPageCenter}
        {}

您能给出实现最后一个代码功能的代码吗?谢谢。

答案1

LaTeX3 的编程expl3层带有许多用于此类目的的实用函数。该模型提供了不同的数据结构和可对其进行操作的算法。其中一些有语句switch,请参阅下面的示例。

对于您的用例来说,这\str_case:nn是合适的。如果没有找到匹配项,则会发出错误信号。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\msg_new:nnn
  { switchcase }
  { no-match }
  { There~is~no~entry~`#1'~in~the~switch~statement! }

\NewDocumentCommand \switchcase { m m }
  {
    \str_case:nnF { #1 } { #2 } { \msg_error:nnn { switchcase } { no-match } { #1 } }
  }

\ExplSyntaxOff

\newcommand\whatever[1]{%
  \switchcase{#1}%
  {
    {ul}{\let\position\AtPageUpperLeft}
    {ll}{\let\position\AtPageLowerLeft}
    {pc}{\let\position\AtPageCenter}
  }%
}

% Sentinel
\newcommand*\AtPageUpperLeft{AtPageUpperLeft}
\newcommand*\AtPageLowerLeft{AtPageLowerLeft}
\newcommand*\AtPageCenter   {AtPageCenter}


\begin{document}

\whatever{ul}\position

\whatever{ll}\position

\whatever{pc}\position

\whatever{rubbish}\position % error!

\end{document}

对于宏,您可以使用\tl_case:nn

在此处输入图片描述

如果你想以与 catcode 无关的方式比较字符串,请使用\str_case:nn

在此处输入图片描述

对于整数,有\int_case:nn

在此处输入图片描述

对于尺寸,有\dim_case:nn

在此处输入图片描述

答案2

这是一个相当通用的 switch case 宏,基于expl3。语法是

\switchcondition[<type>]{<input>}[<other>]{<cases>}

其中是、或(默认)中的一个,是<type>针对案例进行测试的参数,是如果没有匹配的案例要做什么,是形式为stringtokenintegerdimenstring<input><other><cases>

{<case-1>}{<code-1>}
{<case-2>}{<code-2>}
[...]
{<case-n>}{<code-n>}

宏本身是完全可扩展的,但当然,只有当<other>并且<code-k>在每种情况下都完全可扩展时,才能利用此功能。

这是一个例子。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\switchcondition}{O{string}mmO{}}
 {
  \use:c { lyl_#1_switch:nnn } { #2 } { #3 } { #4 }
 }

\cs_new:Nn \lyl_string_switch:nnn
 {
  \str_case:nnF { #1 } { #2 } { #3 }
 }
\cs_new:Nn \lyl_token_switch:nnn
 {
  \tl_case:nnF { #1 } { #2 } { #3 }
 }
\cs_new:Nn \lyl_integer_switch:nnn
 {
  \int_case:nnF { #1 } { #2 } { #3 }
 }
\cs_new:Nn \lyl_dimen_switch:nnn
 {
  \dim_case:nnF { #1 } { #2 } { #3 }
 }
\ExplSyntaxOff

\newcommand{\placement}[1]{%
  \switchcondition{#1}{
    {ul}{\let\position\AtPageUpperLeft}
    {ll}{\let\position\AtPageLowerLeft}
    {ur}{\let\position\AtPageUpperRight}
    {lr}{\let\position\AtPageLowerRight}
  }[\let\position\ERROR]%
}

% whatever these should do
\providecommand{\AtPageUpperLeft}{APUL}
\providecommand{\AtPageLowerLeft}{APLL}
\providecommand{\AtPageUpperRight}{APUR}
\providecommand{\AtPageLowerRight}{APLR}
\providecommand{\ERROR}{ERROR}

\newcommand{\foo}[1]{%
  \switchcondition[integer]{#1}{
    {1}{One}
    {20}{Twenty}
    {42}{The answer!}
  }[Uninteresting number]%
}

\begin{document}

\placement{ul}\texttt{\meaning\position}

\placement{ll}\texttt{\meaning\position}

\placement{ur}\texttt{\meaning\position}

\placement{lr}\texttt{\meaning\position}

\placement{xy}\texttt{\meaning\position}

\foo{1}

\foo{6*7}

\foo{3456}

\end{document}

在此处输入图片描述

答案3

你也可以让 TeX 的 csname 哈希表为你进行查找,因此

\def\positionul{\let\position\AtPageUpperLeft}
\def\positionll{\let\position\AtPageLowerLeft}
\def\positionpc{\let\position\AtPageCenter}

然后在你没有显示的宏中,想要使用#1ul或者ll只是pc使用

\csname position#1\endcsname

并且它将执行\positionll如果#1ll

相关内容