我希望围绕switch-case
LaTeX 环境构建命令,类似于下面的示例:
\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
虽然对原作者来说可能已经太晚了,但我刚刚设计出了自己的开关,并想在这里与未来的读者分享。我的解决方案仅使用包xifthen
(ifthen
也足够了,但我已经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}