实现 switch 案例

实现 switch 案例

我希望围绕switch-caseLaTeX 环境构建命令,类似于下面的示例:

\documentclass{article}

\usepackage{xstring}

\newcommand{\dothis}[1]{%
\IfStrEqCase{#1}{{a}{so you typed a}
    {b}{now this is b}
    {c}{you want me to do c?}}
    [nada]
}

\begin{document}

\dothis{a}

\dothis{b}

\dothis{c}

\dothis{e}

\end{document}

我的问题是它需要xstring软件包。还有其他方法可以做到这一点吗?最好不要加载其他软件包并避免令人不齿的\if-\else-\fi语句?

答案1

问题要求避免使用包,因此虽然这是 中使用的方法,但expl3\str_case:nnF已将其重新编码并提供最低限度的支持。我使用的唯一包是pdftexcmds,这是必需的,因为XeTeX\pdfstrcmp调用了 pdfTeX 中的原语\strcmp ,并且必须在 Lua 中为 LuaTeX 实现。没有包也很容易做到这一点,但会掩盖方法:如果需要,请提出单独的问题!

这里的一般思路是设置一个比较循环,其中测试是通过 扩展完成的\pdfstrcmp。每次都会传递测试字符串,如果“tidy up”代码匹配,则插入“true”字符串。如果根本没有匹配,则插入“else”代码。业务\romannumeral意味着它总是需要两个扩展来完成这里的工作:

\documentclass{article}
\usepackage{pdftexcmds}
\makeatletter
\newcommand*{\dothis}[1]{%
  \stringcases
    {#1}%
    {%
      {a}{so you typed a}%
      {b}{now this is b}%
      {c}{you want me to do c?}%
    }%
    {[nada]}%
}
\newcommand{\stringcases}[3]{%
  \romannumeral
    \str@case{#1}#2{#1}{#3}\q@stop
}
\newcommand{\str@case}[3]{%
  \ifnum\pdf@strcmp{\unexpanded{#1}}{\unexpanded{#2}}=\z@
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
    {\str@case@end{#3}}
    {\str@case{#1}}%
}
\newcommand{\str@case@end}{}
\long\def\str@case@end#1#2\q@stop{\z@#1}
\makeatother

\begin{document}

\dothis{a}

\dothis{b}

\dothis{c}

\dothis{e}

\end{document}

答案2

虽然对原作者来说可能已经太晚了,但我刚刚设计出了自己的开关,并想在这里与未来的读者分享。我的解决方案仅使用包xifthenifthen也足够了,但我已经xifthen安装了……)。

% Switch implementation
\usepackage{xifthen}
\newcommand{\ifequals}[3]{\ifthenelse{\equal{#1}{#2}}{#3}{}}
\newcommand{\case}[2]{#1 #2} % Dummy, so \renewcommand has something to overwrite...
\newenvironment{switch}[1]{\renewcommand{\case}{\ifequals{#1}}}{}

% Example: Pick color by ID
\newcommand{\incolor}[2]{
    \begin{switch}{#1}
        \case{1}{\color{red}}
        \case{2}{\color{blue}}
        \case{3}{\color{green}}
        \case{4}{\color{black}}
        #2
    \end{switch}
}

此代码在我的 TeXMaker 中编译得很好(当然,您需要此示例的颜色包,但它不是开关的一部分)。示例使用我选择的 ID 定义的颜色对给定输入进行着色(用法:)\incolor{ID}{Content}。我用它来简写许多东西(例如\lp1,,\lp2... 使用 表示不同颜色的括号\newcommand{\lp}[1]{\incolor{#1}{\langle}})。请随意尝试 ;)

我可以想象将其扩展为仅使用内置控制结构的解决方案,但我现在太懒了,不想这样做,但\ifx应该\else可以解决问题。

答案3

有一个内置函数,\ifcase其工作原理类似于 switch-case,用于解释数字。因此,我将字符串“a”、“b”、“c”翻译为数字 0、1、2。请注意,第一个 case 是 0。它不需要包,非常简单。

\documentclass{article}
\newcommand{\dothis}[1]{%
\ifcase#1\relax so you typed a % Case 0.

\or now this is b % Case 1.

\or you want me to do c? % Case 2.

\else Default case.
\fi
}
\begin{document}
\dothis{0}

\dothis{1}

\dothis{2}

\dothis{3}
\end{document}

答案4

以下是通过宏定义的解决方案(单个测试做出选择):

\documentclass{article}
\makeatletter
\newcommand\addcase[3]{\expandafter\def\csname\string#1@case@#2\endcsname{#3}}
\newcommand\makeswitch[2][]{%
  \newcommand#2[1]{%
    \ifcsname\string#2@case@##1\endcsname\csname\string#2@case@##1\endcsname\else#1\fi%
  }%
}
\makeatother

\makeswitch[nada]\dothis
\addcase\dothis{a}{so you typed a}
\addcase\dothis{b}{so you typed b}
\addcase\dothis{c}{you want me to do c?}

\begin{document}
\dothis{a}

\dothis{b}

\dothis{c}

\dothis{e}

\end{document}

相关内容