我有一个 tex 文件,其中包含一些我自己的自定义函数,其中一个是 switch case 函数。
因为我使用 \input 从其他文档调用此文件,所以我需要将输出变量设置为本地变量。但是,我需要一个本地变量来存储输出,同时迭代循环的其余部分。要么这样做,要么中止循环并转到函数的末尾。
我正在使用 tex maker 和 pdftex
\usepackage{xparse}
\usepackage{fp}
\usepackage{xstring}
\usepackage{ifthen}
\usepackage{printlen}
\usepackage{listofitems}
\usepackage{forloop}
\usepackage{pgffor}
\NewDocumentCommand\SwitchCase{m m}
{
\setsepchar{,/-}
\readlist\Cases{#2}
\FPadd\CaseCount{\Caseslen}{0}
\def\out{}
\foreach \ct in {1,...,\CaseCount}
{
\ifthenelse{\equal{#1}{\Cases[\ct ,1]}}
{
\def\tmp{\Cases[\ct, 2]}
%\tmp
\def\out{\tmp}
}
{}
}
\out
}
%below is a sample of how this code would work
%not exactly how I would use it, but still valid example
\begin{document}
\SwitchCase{hello}{hel-1,he-2,hello-3,Hello-4}
\end{document}
给出示例,函数应该返回 3,但是当我尝试在循环中设置输出变量时,它返回 0 或不返回任何内容。
此功能在我的文档中有很多可能的用途,因此它必须模糊。
附言:如果任何措辞不当,我深感抱歉,因为我的句法和词汇选择并不是最好的。
答案1
您可以不使用此处的所有包来实现该功能:
\documentclass{article}
\makeatletter
\newcommand\SwitchCase[2]{%
\def\tmpa{#1}%
\@for\tmp:=#2\do{\expandafter\zz@switch\tmp\zz@switch}%
}
\def\zz@switch#1-#2\zz@switch{%
\def\tmpb{#1}%
\ifx\tmpa\tmpb#2\fi}
\makeatother
\begin{document}
\SwitchCase{hello}{hel-1,he-2,hello-3,Hello-4}
\end{document}
答案2
这是一个常见的问题:\foreach
循环是成组进行的。
另外,您必须完全扩展的替换文本\tmp
(但您不需要它并且可以直接定义\out
)。
\documentclass{article}
\usepackage{xparse}
\usepackage{fp}
\usepackage{xstring}
\usepackage{ifthen}
\usepackage{printlen}
\usepackage{listofitems}
\usepackage{forloop}
\usepackage{pgffor}
\NewDocumentCommand\SwitchCase{m m}
{%
\setsepchar{,/-}%
\readlist\Cases{#2}%
\foreach \ct in {1,...,\Caseslen}
{%
\ifthenelse{\equal{#1}{\Cases[\ct ,1]}}
{%
\xdef\out{\Cases[\ct, 2]}
}
{}%
}%
\out
}
\begin{document}
\SwitchCase{hello}{hel-1,he-2,hello-3,Hello-4}
\end{document}
输出结果为 3。
请注意未受保护的行尾会产生可能无法被忽略的空格,具体取决于调用宏的上下文。
较短的版本使用expl3
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand\SwitchCase{m m}
{
\clist_map_inline:nn { #2 }
{
\__cdickstein_switchcase_item:nn { #1 } { ##1 }
}
}
\cs_new:Nn \__cdickstein_switchcase_item:nn
{
\__cdickstein_switchcase_item:nw { #1 } #2 \q_stop
}
\cs_new:Npn \__cdickstein_switchcase_item:nw #1 #2 - #3 \q_stop
{
\str_if_eq:nnT { #1 } { #2 } { \clist_map_break:n { #3 } }
}
\ExplSyntaxOff
\begin{document}
\SwitchCase{hello}{hel-1,he-2,hello-3,Hello-4}
\end{document}
这在第一场比赛后就停止了。
可扩展版本再次在第一个匹配处停止。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand\SwitchCase{m m}
{
\__cdickstein_switchcase:nw { #1 } #2 , , \q_nil
}
\cs_new:Npn \__cdickstein_switchcase:nw #1 #2 ,
{
\tl_if_blank:nTF { #2 }
{
\use_none:n
}
{
\__cdickstein_switchcase_item:nw { #1 } #2 \q_stop
\__cdickstein_switchcase:nw { #1 }
}
}
\cs_new:Npn \__cdickstein_switchcase_item:nw #1 #2 - #3 \q_stop
{
\str_if_eq:nnT { #1 } { #2 } { #3 \__cdickstein_swithcase_break:w }
}
\cs_new:Npn \__cdickstein_swithcase_break:w #1 \q_nil {}
\ExplSyntaxOff
\begin{document}
\SwitchCase{hello}{hel-1,he-2,hello-3,Hello-4}
\SwitchCase{x}{x-1,y-2,x-3}
\end{document}