A menudo uso xtring
's \IfStrEqCase
para 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 1
y case 3
es case 4
idé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:
- Relacionado con este tema, pero bastante diferente:Generalice \@ifnextchar para considerar más de un carácter..
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}
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 listofitems
enfoque. 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 \setsepchar
para 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}
Por supuesto, xstring
se puede eliminar del proceso por completo mediante \ifnum
s 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 \msgA
y \msgB
referirse 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@KeepKthOfLArguments
que 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@KeepKthOfLArguments
del primer argumento de para evaluar el número K.
Por lo tanto, debe hacerlo de otra manera, es decir, llamar \UD@KeepKthOfLArguments
desde adentro \IfStrEqCase
para 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}