Присвоить значение локальной переменной в новой команде

Присвоить значение локальной переменной в новой команде

У меня есть 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, либо ничего.

Эта функция имеет множество возможных применений в моих документах, поэтому она должна быть неопределенной.

ps Прошу прощения, если какая-либо формулировка покажется неловкой, я не очень хорош в синтаксисе и выборе слов.

решение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}

Связанный контент