ケースごとに複数の一致を持つ \IfStrEqCase を修正しました

ケースごとに複数の一致を持つ \IfStrEqCase を修正しました

xtring私は条件処理に's をよく使用します\IfStrEqCase。これはうまく機能しますが、現在の動作を拡張して、複数のケースを 1 つの一致にグループ化できるようにする簡単な方法があるかどうか疑問に思っています。

以下の MWE では、、およびの出力はcase 1同じですcase 3case 4、複数の場所でテキストを複製する必要があります。このテキストが長いとエラーが発生しやすくなるため、次のような構文ですべてをまとめることができれば便利です。

\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}]%

参考文献:

ノート:

  • もちろん、解決策の1つはマクロを定義することです

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

    しかし、可能であればそれを避けたいと考えています。

コード:

\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}

答え1

遅いですが、うまく機能しています。コードは入力を操作して、\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}

ここに画像の説明を入力してください

変数の使用は次のように対応できます。

\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}

答え2

アプローチは次のとおりですlistofitems。鍵となるのは、区切り文字の定義方法です。 を使用して\setsepchar{case 1||case 3||case 4/case 2||case 5}、最上位レベルの解析ではケース 1、3、4 を検索します。第 2 層の解析では、ケース 2 と 5 を検索します。解析は を使用して実行されます\readlist\tmp{#1}。次に、\listlen\tmp[]解析レベル 1 のフレーズに沿って分割することで作成された項目の数が表示されます。同様に、\listlen\tmp[1]解析レベル 2 のフレーズに沿って分割することで作成された項目の数が表示されます。フレーズが見つかった場合、答えは 2 で、解析されたフレーズの前後のスペース (null の場合でも) を示します。答えが 1 の場合、フレーズは解析されなかったことを意味します。

このアプローチでは、3 つ以上の解析層を設定するために使用するだけで、2 つ以上のレベルを設定することもできます\setsepchar

\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}

ここに画像の説明を入力してください

もちろん、xstringネストされた を使用することで、プロセスから を完全に排除することもできます\ifnum

\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}

オリジナルの回答

\msgAと を定義して、大文字と小文字を区別して間接的に参照するだけではいかがでしょうか\msgB。これにより、同一のメッセージを複数回再入力する必要がなくなります。

\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}

答え3

数年前、私は、任意の数の無制限の引数から任意の無制限の引数を選択できるルーチンを作成しました\UD@KeepKthOfLArguments。このルーチンは、再帰により、TeX のマクロ プログラミングに通常課せられる 9 個の引数制限に縛られません。

残念ながら、\IfStrEqCase自体は完全に展開可能ではないため、\UD@KeepKthOfLArguments数値 K を評価するために の最初の引数内で使用することができません。したがって、別の方法、つまり内から を呼び出して3 つの引数のいずれかを選択する必要
があります 。\UD@KeepKthOfLArguments\IfStrEqCase

\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}

ちなみに、純粋な拡張コンテキスト内でこのような選択を行う場合は、区切られた引数を使用する戦略の例を次に示します。

\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}

関連情報