\IfStrEqCase modificado con múltiples coincidencias por caso

\IfStrEqCase modificado con múltiples coincidencias por caso

A menudo uso xtring's \IfStrEqCasepara el procesamiento condicional. Esto funciona muy bien, pero me pregunto si existe una manera fácil de mejorar el comportamiento actual y permitir agrupar varios casos en una sola coincidencia.

En el MWE siguiente, la salida para case 1y case 3es case 4idéntica, pero tengo que duplicar el texto en varios lugares. Cuando este texto es largo, es bastante propenso a errores, por lo que sería bueno poder agruparlos todos en una sintaxis similar a:

\IfStrEqCaseModified{#1}{% <--- Need to define this
    {{case 1}{case 3}{case 4}}{%
        some long text which is identical for case 1, case 3 and case 4.%
    }%
    {{case 2}{case 5}}{%
        other text for case 2 and case 5.%
    }%
}[{Error: Unknown parameter ``#1'' to ConditionalTextDesired}]%

Referencias:

Notas:

  • Una solución, por supuesto, sería definir una macro.

    \newcommand{\RepeatedText}{some long text which is identical for case 1, case 3 and case 4.}
    

    pero preferiría evitarlo si es posible.

Código:

\documentclass{article}
\usepackage{xstring}

\newcommand*{\ConditionalText}[1]{%
    \IfStrEqCase{#1}{%
        {case 1}{%
            some long text which is identical for case 1, case 3 and case 4.%
        }%
        {case 2}{%
            other text for case 2 and case 5.%
        }%
        {case 3}{%
            some long text which is identical for case 1, case 3 and case 4.%
        }%
        {case 4}{%
            some long text which is identical for case 1, case 3 and case 4.%
        }%
        {case 5}{%
            other text for case 2 and case 5.%
        }%
    }[{Error: Unknown parameter ``#1'' to ConditionalText}]%
}%

\newcommand*{\ConditionalTextDesired}[1]{%
    \IfStrEqCaseModified{#1}{% <--- Need to define this
        {{case 1}{case 3}{case 4}}{%
            some long text which is identical for case 1, case 3 and case 4.%
        }%
        {{case 2}{case 5}}{%
            other text for case 2 and case 5.%
        }%
    }[{Error: Unknown parameter ``#1'' to ConditionalTextDesired}]%
}%


\begin{document}
    \par\ConditionalText{case 1}
    \par\ConditionalText{case 2}
    \par\ConditionalText{case 3}
    \par\ConditionalText{case 4}
    \par\ConditionalText{case 5}

    %\bigskip\par
    %This should produce identical output
    %\par\ConditionalTextDesired{case 1}
    %\par\ConditionalTextDesired{case 2}
    %\par\ConditionalTextDesired{case 3}
    %\par\ConditionalTextDesired{case 4}
    %\par\ConditionalTextDesired{case 5}
\end{document}

Respuesta1

Lento, pero funcionando. El código masajea la entrada para que sea aceptable para\str_case:nnTF

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\cs_new_protected:Nn \grill_str_multicase:nnTF
 {
  \seq_set_split:Nnn \l__grill_str_multicase_cases_seq { } { #2 }
  \tl_clear:N \l__grill_str_multicase_cases_tl
  \int_step_inline:nnnn { 1 } { 2 } { \seq_count:N \l__grill_str_multicase_cases_seq }
   {
    \seq_set_split:Nnx \l__grill_str_multicase_subcases_seq { }
     { \seq_item:Nn \l__grill_str_multicase_cases_seq { ##1 } }
    \seq_map_inline:Nn \l__grill_str_multicase_subcases_seq
     {
      \tl_put_right:Nx \l__grill_str_multicase_cases_tl
       {
        {\exp_not:n{####1}}{\seq_item:Nn \l__grill_str_multicase_cases_seq { ##1 + 1}}
       }
     }
   }
   \str_case:nVTF { #1 } \l__grill_str_multicase_cases_tl { #3 } { #4 }
 }
\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }
\cs_new_protected:Nn \grill_str_multicase:nn
 {
  \grill_str_multicase:nnTF { #1 } { #2 } { } { }
 }
\cs_new_protected:Nn \grill_str_multicase:nnT
 {
  \grill_str_multicase:nnTF { #1 } { #2 } { #3 } { }
 }
\cs_new_protected:Nn \grill_str_multicase:nnF
 {
  \grill_str_multicase:nnTF { #1 } { #2 } { } { #3 }
 }

\NewDocumentCommand{\IfStringCaseX}{mmo}
 {
  \IfNoValueTF{#3}
   { \grill_str_multicase:nn { #1 } { #2 } }
   { \grill_str_multicase:nnF { #1 } { #2 } { #3 } }
 }
\ExplSyntaxOff

\newcommand{\ConditionalText}[1]{%
  \IfStringCaseX{#1}
   {
    {{case 1}{case 3}{case 4}}
    {%
     some long text which is identical for case 1, case 3 and case 4.%
    }
    {{case 2}{case 5}}
    {%
     other text for case 2 and case 5.%
    }%
   }[{Error: Unknown parameter ``#1'' to ConditionalText}]%
}

\begin{document}

\ConditionalText{case 1}

\ConditionalText{case 2}

\ConditionalText{case 3}

\ConditionalText{case 4}

\ConditionalText{case 5}

\ConditionalText{case 6}

\end{document}

ingrese la descripción de la imagen aquí

El uso de variables se puede acomodar:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\cs_new_protected:Nn \grill_str_multicase:nnTF
 {
  \seq_set_split:Nnn \l__grill_str_multicase_cases_seq { } { #2 }
  \tl_clear:N \l__grill_str_multicase_cases_tl
  \int_step_inline:nnnn { 1 } { 2 } { \seq_count:N \l__grill_str_multicase_cases_seq }
   {
    \seq_set_split:Nnx \l__grill_str_multicase_subcases_seq { }
     { \seq_item:Nn \l__grill_str_multicase_cases_seq { ##1 } }
    \seq_map_inline:Nn \l__grill_str_multicase_subcases_seq
     {
      \tl_put_right:Nx \l__grill_str_multicase_cases_tl
       {
        {\exp_not:n{####1}}{\seq_item:Nn \l__grill_str_multicase_cases_seq { ##1 + 1}}
       }
     }
   }
   \str_case:nVTF { #1 } \l__grill_str_multicase_cases_tl { #3 } { #4 }
 }
\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }
\cs_new_protected:Nn \grill_str_multicase:nn
 {
  \grill_str_multicase:nnTF { #1 } { #2 } { } { }
 }
\cs_new_protected:Nn \grill_str_multicase:nnT
 {
  \grill_str_multicase:nnTF { #1 } { #2 } { #3 } { }
 }
\cs_new_protected:Nn \grill_str_multicase:nnF
 {
  \grill_str_multicase:nnTF { #1 } { #2 } { } { #3 }
 }
\cs_generate_variant:Nn \grill_str_multicase:nn { o }
\cs_generate_variant:Nn \grill_str_multicase:nnF { o }

\NewDocumentCommand{\IfStringCaseX}{mmo}
 {
  \IfNoValueTF{#3}
   { \grill_str_multicase:nn { #1 } { #2 } }
   { \grill_str_multicase:nnF { #1 } { #2 } { #3 } }
 }
\NewDocumentCommand{\IfStringCaseXO}{mmo}
 {
  \IfNoValueTF{#3}
   { \grill_str_multicase:on { #1 } { #2 } }
   { \grill_str_multicase:onF { #1 } { #2 } { #3 } }
 }
\ExplSyntaxOff

\NewDocumentCommand{\ConditionalText}{sm}{%
  \IfBooleanTF{#1}{\IfStringCaseXO{#2}}{\IfStringCaseX{#2}}%
   {
    {{case 1}{case 3}{case 4}}
    {%
     some long text which is identical for case 1, case 3 and case 4.%
    }
    {{case 2}{case 5}}
    {%
     other text for case 2 and case 5.%
    }%
   }[{Error: Unknown parameter ``#2'' to ConditionalText}]%
}
\ExplSyntaxOff

\begin{document}

\ConditionalText{case 1}

\ConditionalText{case 2}

\ConditionalText{case 3}

\ConditionalText{case 4}

\ConditionalText{case 5}

\ConditionalText{case 6}

\def\casesix{case 6}

\ConditionalText*{\casesix}

\end{document}

Respuesta2

He aquí un listofitemsenfoque. La clave está en cómo se define el separador. Utilizando \setsepchar{case 1||case 3||case 4/case 2||case 5}, el análisis de nivel superior busca los casos 1, 3 y 4. El análisis de segundo nivel busca los casos 2 y 5. El análisis se realiza con \readlist\tmp{#1}. Luego, \listlen\tmp[]revela cuántos elementos se crean al dividirlos a lo largo de la frase del nivel 1 de análisis. Asimismo, \listlen\tmp[1]revela cuántos elementos se crean al dividirlos a lo largo de la frase de nivel 2 de análisis. Si se encuentra la frase, la respuesta es 2, lo que indica el espacio (incluso si es nulo) antes y después de la frase analizada, y si la respuesta es 1, significa que no se analizó ninguna frase.

El enfoque también permitirá establecer más de 2 niveles, simplemente utilizándolo \setsepcharpara establecer 3 o más niveles de análisis.

\documentclass{article}
\usepackage{xstring,listofitems}
\newcommand*{\ConditionalText}[1]{%
  \setsepchar{case 1||case 3||case 4/case 2||case 5/case 6}
  \readlist\tmp{#1}%
  \IfStrEqCase{\listlen\tmp[]\listlen\tmp[1]\listlen\tmp[1,1]}{%
      {211}{some long text which is identical for case 1, case 3 and case 4.}%
      {121}{other text for case 2 and case 5.}%
      {112}{for case 6 only.}%
  }[{Error: Unknown parameter ``#1'' to ConditionalText}]%
}
\begin{document}
    \par\ConditionalText{case 1}
    \par\ConditionalText{case 2}
    \par\ConditionalText{case 3}
    \par\ConditionalText{case 4}
    \par\ConditionalText{case 5}
    \par\ConditionalText{case 6}
    \par\ConditionalText{case 7}
\end{document}

ingrese la descripción de la imagen aquí

Por supuesto, xstringse puede eliminar del proceso por completo mediante \ifnums anidados:

\documentclass{article}
\usepackage{listofitems}
\setsepchar{\\}
\readlist*\thecases{
some long text which is identical for case 1, case 3 and case 4.\\
other text for case 2 and case 5.\\
for case 6 only.
}
\newcommand*{\ConditionalText}[1]{%
  \setsepchar{case 1||case 3||case 4/case 2||case 5/case 6}
  \readlist\tmp{#1}%
  \edef\tmpnum{\listlen\tmp[]\listlen\tmp[1]\listlen\tmp[1,1]}
  \ifnum\tmpnum=211\relax\thecases[1]%
  \else\ifnum\tmpnum=121\relax\thecases[2]%
  \else\ifnum\tmpnum=112\relax\thecases[3]%
  \else Error: Unknown parameter ``#1'' to ConditionalText%
  \fi\fi\fi
}
\begin{document}
    \par\ConditionalText{case 1}
    \par\ConditionalText{case 2}
    \par\ConditionalText{case 3}
    \par\ConditionalText{case 4}
    \par\ConditionalText{case 5}
    \par\ConditionalText{case 6}
    \par\ConditionalText{case 7}
\end{document}

RESPUESTA ORIGINAL

¿Por qué no simplemente definirlos \msgAy \msgBreferirse a ellos indirectamente por caso? Esto evita la necesidad de volver a escribir el mensaje idéntico varias veces.

\documentclass{article}
\usepackage{xstring}
\def\msgA{some long text which is identical for case 1, case 3 and case 4.}
\def\msgB{other text for case 2 and case 5.}
\newcommand*{\ConditionalText}[1]{%
    \IfStrEqCase{#1}{%
        {case 1}{\msgA}%
        {case 2}{\msgB}%
        {case 3}{\msgA}%
        {case 4}{\msgA}%
        {case 5}{\msgB}%
    }[{Error: Unknown parameter ``#1'' to ConditionalText}]%
}
\begin{document}
    \par\ConditionalText{case 1}
    \par\ConditionalText{case 2}
    \par\ConditionalText{case 3}
    \par\ConditionalText{case 4}
    \par\ConditionalText{case 5}
\end{document}

Respuesta3

Hace algunos años escribí una rutina \UD@KeepKthOfLArgumentsque le permite elegir un argumento arbitrario no delimitado entre una cantidad arbitraria de argumentos no delimitados que, debido a la recursividad, no está sujeto al límite de 9 argumentos generalmente impuesto en la macroprogramación de TeX.

Desafortunadamente \IfStrEqCase, no es completamente expandible y por lo tanto no se puede usar dentro \UD@KeepKthOfLArgumentsdel primer argumento de para evaluar el número K.
Por lo tanto, debe hacerlo de otra manera, es decir, llamar \UD@KeepKthOfLArgumentsdesde adentro \IfStrEqCasepara seleccionar uno de los tres argumentos:

\documentclass{article}
\usepackage{xstring}

\makeatletter
%%=========================================================================
%% Paraphernalia:
%%    \UD@firstoftwo, \UD@secondoftwo, \UD@PassFirstToSecond
%%.........................................................................
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
%%-------------------------------------------------------------------------
%% Check whether argument is empty:
%%.........................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
%%
%% A concern in his posting is that the argument is hit with \string
%% after some expansions which in edge cases might result in unbalancing
%% surrounding \if..\fi-constructs if the macro is used inside of such
%% \if..\fi-constructs.
%%
%% That challenging concern sickened me. ;-)
%%
%% Therefore I decided to implerment a variant where this cannot happen
%% as expansion is forced by \romannumeral:
%%
%% After the first expansion-step, \string is not applied yet.
%% After the second expansion-step, any possibly disturbing remainders
%% are already removed due to \romannumeral-expansion.
%%
%% No eTeX- or whatsoever extensions. No \if.. .Only \romannumeral,
%% digit 0, space token for terminating \romannumeral-expansion,
%% \string, \expandafter, \UD@firstoftwo, \UD@secondoftwo, {, }.
%%
%% May 20, 2016
%%
%% Ulrich Diez (e-mail: [email protected])
%%
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral0\expandafter\UD@secondoftwo\string{\expandafter
  \UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
  \UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
  \UD@secondoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@firstoftwo}%
}%
%%-------------------------------------------------------------------------
%% Keep only the K-th of L consecutive undelimited arguments.
%%   ( IF K < 1 OR K > L just remove L consecutive undelimited arguments. )
%%.........................................................................
%% \UD@KeepKthOfLArguments{<integer number K>}%
%%                        {<integer number L>}%
%%                        {<Tokens to insert before K-th argument>}%
%%                        <L consecutive undelimited arguments>
%%
%% If K >= 1 and K <= L  yields:
%%       <Tokens to insert before K-th argument><K-th undelimited argument>
%% If K < 1 or K > L
%%       (-> there is no K-th argument in the set
%%           of <L consecutive undelimited arguments> )
%% yields:
%%       <Tokens to insert before K-th argument>
%%
%% Examples:
%%
%% X\UD@KeepKthOfLArguments{3}{7}{<Tokens to insert>}{A}{B}{C}{D}{E}{F}{G}X
%% yields: X<Tokens to insert>CX
%%
%% X\UD@KeepKthOfLArguments{5}{2}{<Tokens to insert>}{A}{B}X
%% yields X<Tokens to insert>X
%%
%% X\UD@KeepKthOfLArguments{0}{2}{<Tokens to insert>}{A}{B}X
%% yields X<Tokens to insert>X
%%
%% X\romannumeral0%
%%  \UD@KeepKthOfLArguments{3}{7}{ <Tokens to insert>}{A}{B}{C}{D}{E}{F}{G}X
%% yields: X\romannumeral0 <Tokens to insert>CX
%% yields: X<Tokens to insert>CX
%% In case of embedding the whole thing in other expansion-contexts,
%% you need to have "hit" \romannumeral by only one \expandafter-chain for
%% obtaining the result...
%%
%% January 17, 2005
%%
%% Ulrich Diez (e-mail: [email protected])
%%
\newcommand\UD@KeepKthOfLArguments[2]{%
  \expandafter\UD@KeepKthOfLArgumentsA
  \expandafter{\romannumeral\number\number#1 000\expandafter}%
  \expandafter{\romannumeral\number\number#2 000}%
}%
\newcommand\UD@KeepKthOfLArgumentsA[3]{%
  \UD@CheckWhetherNull{#1}{%
    \UD@RemoveNArguments{#2}{#3}{}%
  }{%
    \expandafter\UD@PassFirstToSecond
    \expandafter{%
    \UD@firstoftwo{}#1}{\UD@KeepKthOfLArgumentsB{#1}{#2}}{#2}{#3}%
  }%
}%
\newcommand\UD@KeepKthOfLArgumentsB[5]{%
  \UD@CheckWhetherNull{#1}{%
     \UD@RemoveNArguments{#3}{\UD@RemoveNArguments{#2}{#5}}{}%
  }{%
    \UD@CheckWhetherNull{#2}{%
      \UD@RemoveNArguments{#4}{#5}{}%
    }{%
      \expandafter\UD@PassFirstToSecond
      \expandafter{%
      \UD@firstoftwo{}#2}{\expandafter\UD@KeepKthOfLArgumentsB
                       \expandafter{%
                       \UD@firstoftwo{}#1}}{#3}{#4}{#5}%
    }%
  }%
}%
\newcommand\UD@RemoveNArguments[3]{%
  \UD@CheckWhetherNull{#1}{#2#3}{%
    \UD@firstoftwo{%
      \expandafter\UD@RemoveNArguments
      \expandafter{\UD@firstoftwo{}#1}{#2}{#3}%
    }%
  }%
}%
%----------------------------------------------------------------------------
%----------------------------------------------------------------------------
\newcommand*{\ConditionalTextDesired}[1]{%
  % \IfStrEqCase will deliver the call to \UD@KeepKthOfLArguments plus
  % \UD@KeepKthOfLArguments's first argument:
  \IfStrEqCase{#1}{%
       {case 1}{\UD@KeepKthOfLArguments{1}}%
       {case 2}{\UD@KeepKthOfLArguments{2}}%
       {case 3}{\UD@KeepKthOfLArguments{1}}%
       {case 4}{\UD@KeepKthOfLArguments{1}}%
       {case 5}{\UD@KeepKthOfLArguments{2}}%
  }[{\UD@KeepKthOfLArguments{3}}]%
  % Here come the remaining arguments of \UD@KeepKthOfLArguments:
  {3}{}%
  {some long text which is identical for case 1, case 3 and case 4.}%
  {other text for case 2 and case 5.}%
  {Error: Unknown parameter ``#1'' to ConditionalText.}%
}%
\makeatother

\begin{document}
    \par\ConditionalTextDesired{case 1}
    \par\ConditionalTextDesired{case 2}
    \par\ConditionalTextDesired{case 3}
    \par\ConditionalTextDesired{case 4}
    \par\ConditionalTextDesired{case 5}
\end{document}

Por cierto: en caso de que desee realizar dicha elección dentro de contextos de expansión pura, aquí hay un ejemplo de una estrategia basada en el uso de argumentos delimitados:

\documentclass{article}
\makeatletter
%%=========================================================================
%% Paraphernalia:
%%    \UD@firstoftwo, \UD@secondoftwo, \UD@PassFirstToSecond
%%.........................................................................
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
%%-------------------------------------------------------------------------
%% Check whether argument is empty:
%%.........................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
%%
%% A concern in his posting is that the argument is hit with \string
%% after some expansions which in edge cases might result in unbalancing
%% surrounding \if..\fi-constructs if the macro is used inside of such
%% \if..\fi-constructs.
%%
%% That challenging concern sickened me. ;-)
%%
%% Therefore I decided to implerment a variant where this cannot happen
%% as expansion is forced by \romannumeral:
%%
%% After the first expansion-step, \string is not applied yet.
%% After the second expansion-step, any possibly disturbing remainders
%% are already removed due to \romannumeral-expansion.
%%
%% No eTeX- or whatsoever extensions. No \if.. .Only \romannumeral,
%% digit 0, space token for terminating \romannumeral-expansion,
%% \string, \expandafter, \UD@firstoftwo, \UD@secondoftwo, {, }.
%%
%% May 20, 2016
%%
%% Ulrich Diez (e-mail: [email protected])
%%
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral0\expandafter\UD@secondoftwo\string{\expandafter
  \UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
  \UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
  \UD@secondoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@firstoftwo}%
}%
%%-------------------------------------------------------------------------
%% Keep only the K-th of L consecutive undelimited arguments.
%%   ( IF K < 1 OR K > L just remove L consecutive undelimited arguments. )
%%.........................................................................
%% \UD@KeepKthOfLArguments{<integer number K>}%
%%                        {<integer number L>}%
%%                        {<Tokens to insert before K-th argument>}%
%%                        <L consecutive undelimited arguments>
%%
%% If K >= 1 and K <= L  yields:
%%       <Tokens to insert before K-th argument><K-th undelimited argument>
%% If K < 1 or K > L
%%       (-> there is no K-th argument in the set
%%           of <L consecutive undelimited arguments> )
%% yields:
%%       <Tokens to insert before K-th argument>
%%
%% Examples:
%%
%% X\UD@KeepKthOfLArguments{3}{7}{<Tokens to insert>}{A}{B}{C}{D}{E}{F}{G}X
%% yields: X<Tokens to insert>CX
%%
%% X\UD@KeepKthOfLArguments{5}{2}{<Tokens to insert>}{A}{B}X
%% yields X<Tokens to insert>X
%%
%% X\UD@KeepKthOfLArguments{0}{2}{<Tokens to insert>}{A}{B}X
%% yields X<Tokens to insert>X
%%
%% X\romannumeral0%
%%  \UD@KeepKthOfLArguments{3}{7}{ <Tokens to insert, be aware of the space behind the opening brace!>}{A}{B}{C}{D}{E}{F}{G}X
%% yields: X\romannumeral0 <Tokens to insert>CX
%% yields: X<Tokens to insert>CX
%% In case of embedding the whole thing in other expansion-contexts,
%% you need to have "hit" \romannumeral by only one \expandafter-chain for
%% obtaining the result...
%%
%% January 17, 2005
%%
%% Ulrich Diez (e-mail: [email protected])
%%
\newcommand\UD@KeepKthOfLArguments[2]{%
  \expandafter\UD@KeepKthOfLArgumentsA
  \expandafter{\romannumeral\number\number#1 000\expandafter}%
  \expandafter{\romannumeral\number\number#2 000}%
}%
\newcommand\UD@KeepKthOfLArgumentsA[3]{%
  \UD@CheckWhetherNull{#1}{%
    \UD@RemoveNArguments{#2}{#3}{}%
  }{%
    \expandafter\UD@PassFirstToSecond
    \expandafter{%
    \UD@firstoftwo{}#1}{\UD@KeepKthOfLArgumentsB{#1}{#2}}{#2}{#3}%
  }%
}%
\newcommand\UD@KeepKthOfLArgumentsB[5]{%
  \UD@CheckWhetherNull{#1}{%
     \UD@RemoveNArguments{#3}{\UD@RemoveNArguments{#2}{#5}}{}%
  }{%
    \UD@CheckWhetherNull{#2}{%
      \UD@RemoveNArguments{#4}{#5}{}%
    }{%
      \expandafter\UD@PassFirstToSecond
      \expandafter{%
      \UD@firstoftwo{}#2}{\expandafter\UD@KeepKthOfLArgumentsB
                       \expandafter{%
                       \UD@firstoftwo{}#1}}{#3}{#4}{#5}%
    }%
  }%
}%
\newcommand\UD@RemoveNArguments[3]{%
  \UD@CheckWhetherNull{#1}{#2#3}{%
    \UD@firstoftwo{%
      \expandafter\UD@RemoveNArguments
      \expandafter{\UD@firstoftwo{}#1}{#2}{#3}%
    }%
  }%
}%
%%-------------------------------------------------------------------------
%% Check whether argument contains no exclamation-mark on top-brace-level:
%%.........................................................................
%% \UD@CheckWhetherNoExclamationMark{<Argument which is to be checked>}%
%%                  {<Tokens to be delivered in case that
%%                    argument which is to be checked does not contain !>}%
%%                  {<Tokens to be delivered in case that
%%                    argument which is to be checked does contain !>}%
\long\def\UD@RemoveToExclamationMark#1!{}%
\long\def\UD@CheckWhetherNoExclamationMark#1{%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@RemoveToExclamationMark#1!}%
}%
%%-------------------------------------------------------------------------
%% Fork depending on some tokens:
%%.........................................................................
%% \ConditionalTextDesired{<Argument which is to be checked>}%
%%           {<Tokens to be delivered in case <Argument which is to be checked> is "case 1" or "case 3" or "case 4">}%
%%           {<Tokens to be delivered in case <Argument which is to be checked> is "case 2" or "case 5" >}%
%%
%% In case <Argument which is to be checked> is neither "case 1" nor
%% "case 2" the phrase "Error: Unknown parameter ``<Argument which is
%% to be checked>'' to \ConditionalTextDesired." will be delivered.
%%
\newcommand\@ConditionalTextDesired{}%
\long\def\@ConditionalTextDesired%
   #1!!case 1!case 2!case 3!case 4!case 5!#2#3!!!!{#2}%
\newcommand\ConditionalTextDesired[1]{%
  \romannumeral0%
  \UD@KeepKthOfLArguments{%
    \UD@CheckWhetherNoExclamationMark{#1}{%
      \@ConditionalTextDesired
      !#1!case 1!case 2!case 3!case 4!case 5!{1}%<- #1 is EMPTY
      !!#1!case 2!case 3!case 4!case 5!{2}% <- #1 = case 1
      !!case 1!#1!case 3!case 4!case 5!{3}% <- #1 = case 2
      !!case 1!case 2!#1!case 4!case 5!{2}% <- #1 = case 3
      !!case 1!case 2!case 3!#1!case 5!{2}% <- #1 = case 4
      !!case 1!case 2!case 3!case 4!#1!{3}% <- #1 = case 5
      !!case 1!case 2!case 3!case 4!case 5!{1}% <- #1 = something else without exclamation mark
      !!!!%
    }{1}% <- #1 = something else with exclamation mark
  }{3}{ }% <- The remaining arguments of \UD@KeepKthOfLArguments.
  % You could put the three text-arguments into the macro at this place.
  % You can also provide only the one here, where the macro-parameter #1
  % is needed and provide the other ones at run-time of the macro.
  % The latter will be done for demonstration-purposes.
  {%
    Error: Unknown parameter ``#1'' to \texttt{\string\ConditionalTextDesired}.%
    %In case eTeX-extensions are available you might wish to use \detokenize:
    %Error: Unknown parameter ``\detokenize{#1}'' to \texttt{\string\ConditionalTextDesired}.%
  }%
}%
\makeatother

\begin{document}
% This should yield "Error: Unknown parameter ``'' to \ConditionalTextDesired."
\ConditionalTextDesired{}
                       {some long text which is identical for case 1, case 3 and case 4.}%
                       {other text for case 2 and case 5.}%

% This should yield "Error: Unknown parameter ``!case 1'' to \ConditionalTextDesired."
\ConditionalTextDesired{!case 1}%
                       {some long text which is identical for case 1, case 3 and case 4.}%
                       {other text for case 2 and case 5.}%

% This should yield "Error: Unknown parameter ``case 6'' to \ConditionalTextDesired."
\ConditionalTextDesired{case 6}%
                       {some long text which is identical for case 1, case 3 and case 4.}%
                       {other text for case 2 and case 5.}%

% This should yield "some long text which is identical for case 1, case 3 and case 4."
\ConditionalTextDesired{case 1}%
                       {some long text which is identical for case 1, case 3 and case 4.}%
                       {other text for case 2 and case 5.}%

% This should yield "some long text which is identical for case 1, case 3 and case 4."
\ConditionalTextDesired{case 3}%
                       {some long text which is identical for case 1, case 3 and case 4.}%
                       {other text for case 2 and case 5.}%

% This should yield "some long text which is identical for case 1, case 3 and case 4."
\ConditionalTextDesired{case 4}%
                       {some long text which is identical for case 1, case 3 and case 4.}%
                       {other text for case 2 and case 5.}%

% This should yield "other text for case 2 and case 5."
\ConditionalTextDesired{case 2}%
                       {some long text which is identical for case 1, case 3 and case 4.}%
                       {other text for case 2 and case 5.}%

% This should yield "other text for case 2 and case 5."
\ConditionalTextDesired{case 5}%
                       {some long text which is identical for case 1, case 3 and case 4.}%
                       {other text for case 2 and case 5.}%

\end{document}

información relacionada