
Ich habe eine Tex-Datei mit einigen meiner eigenen benutzerdefinierten Funktionen, von denen eine eine Switch-Case-Funktion ist.
Da ich \input verwende, um diese Datei aus anderen Dokumenten aufzurufen, muss die Ausgabevariable lokal sein. Ich brauche jedoch eine lokale Variable, um die Ausgabe zu speichern, während ich den Rest der Schleife durchlaufe. Entweder das oder ich breche die Schleife ab und gehe zum Ende der Funktion.
Ich verwende Tex Maker und 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}
In diesem Beispiel sollte die Funktion 3 zurückgeben. Wenn ich jedoch versuche, die Ausgabevariable in der Schleife festzulegen, gibt sie entweder 0 oder nichts zurück.
Diese Funktion hat in meinen Dokumenten viele mögliche Verwendungszwecke und muss daher vage bleiben.
P.S.: Ich entschuldige mich, wenn die Formulierungen etwas umständlich sind, ich bin nicht der Beste, was Syntax und Wortwahl angeht.
Antwort1
Sie können die Funktionalität implementieren, ohne alle Pakete hier zu verwenden:
\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}
Antwort2
Es ist das übliche Problem: \foreach
Zyklen werden in einer Gruppe durchgeführt.
Außerdem müssen Sie den Ersetzungstext von vollständig erweitern \tmp
(dies ist jedoch nicht erforderlich und kann direkt definiert werden \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}
Dies gibt 3 aus.
Achten Sie auf ungeschützte Zeilenenden, die Leerzeichen erzeugen, die je nach Kontext, in dem das Makro aufgerufen wird, möglicherweise nicht ignoriert werden.
Eine kürzere Version mit 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}
Dies endet beim ersten Spiel.
Eine erweiterbare Version, die wieder beim ersten Match stoppt.
\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}