Costumo usar xtring
's \IfStrEqCase
para processamento condicional. Isso funciona muito bem, mas estou me perguntando se existe uma maneira fácil de melhorar o comportamento atual e permitir agrupar vários casos em uma única correspondência.
No MWE abaixo, a saída para case 1
, case 3
e case 4
é idêntica, mas tenho que duplicar o texto em vários lugares. Quando este texto é longo, é bastante propenso a erros, então seria bom poder agrupá-los em uma sintaxe semelhante 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}]%
Referências:
- Relacionado a este tópico, mas bem diferente:Generalize \@ifnextchar para considerar mais de um caractere..
Notas:
Uma solução, claro, seria definir uma macro
\newcommand{\RepeatedText}{some long text which is identical for case 1, case 3 and case 4.}
mas preferiria evitar isso, se possível.
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}
Responder1
Lento, mas funcionando. O código massageia a entrada para torná-la aceitável\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}
O uso de variáveis pode ser acomodado:
\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}
Responder2
Aqui está uma listofitems
abordagem. A chave está em como o separador é definido. Usando \setsepchar{case 1||case 3||case 4/case 2||case 5}
, a análise de nível superior procura os casos 1, 3 e 4. A análise de 2ª camada procura os casos 2 e 5. A análise é executada com \readlist\tmp{#1}
. Em seguida, \listlen\tmp[]
revela quantos itens são criados dividindo a frase do nível 1 de análise. Da mesma forma, \listlen\tmp[1]
revela quantos itens são criados dividindo a frase do nível 2 de análise. Se a frase for encontrada, a resposta será 2, indicando o espaço (mesmo que nulo) antes e depois da frase analisada, e se a resposta for 1, significa que nenhuma frase foi analisada.
A abordagem também permitirá que mais de 2 níveis sejam definidos, apenas usando \setsepchar
para definir 3 ou mais níveis de análise.
\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}
Claro, xstring
pode ser totalmente eliminado do processo, por meio de \ifnum
s aninhados:
\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}
RESPOSTA ORIGINAL
Por que não apenas defini-los \msgA
e \msgB
referi-los indiretamente caso a caso? Isso evita a necessidade de redigitar a mesma mensagem diversas vezes.
\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}
Responder3
Há alguns anos, escrevi uma rotina \UD@KeepKthOfLArguments
que permite escolher um argumento arbitrário e indelimitado a partir de uma quantidade arbitrária de argumentos indelimitados que - devido à recursão - não está vinculado ao limite de 9 argumentos normalmente imposto na macroprogramação do TeX.
Infelizmente, \IfStrEqCase
ele próprio não é totalmente expansível e, portanto, não pode ser usado no \UD@KeepKthOfLArguments
primeiro argumento de ' para avaliar o número K.
Portanto, você deve fazer isso de outra maneira, ou seja, chamar \UD@KeepKthOfLArguments
de dentro \IfStrEqCase
para selecionar um dos três 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}
A propósito: caso você queira fazer tal escolha dentro de contextos de expansão pura, aqui está um exemplo de estratégia baseada no 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}