사례당 여러 일치 항목으로 수정된 \IfStrEqCase

사례당 여러 일치 항목으로 수정된 \IfStrEqCase

조건부 처리를 위해 xtring'를 자주 사용합니다 . \IfStrEqCase이것은 훌륭하게 작동하지만 현재 동작을 향상하고 여러 사례를 단일 일치로 그룹화할 수 있는 쉬운 방법이 있는지 궁금합니다.

아래 MWE에서 , 및 의 출력은 case 1동일 case 3하지만 case 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}]%

참고자료:

노트:

  • 물론 한 가지 해결책은 매크로를 정의하는 것입니다.

    \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, 5를 찾습니다. 구문 분석은 로 수행됩니다 \readlist\tmp{#1}. 그런 다음 \listlen\tmp[]구문 분석 수준 1 구문을 따라 분할하여 생성된 항목 수를 나타냅니다. 마찬가지로 \listlen\tmp[1]구문 분석 수준 2 구문에 따라 분할하여 생성된 항목 수를 나타냅니다. 구문이 발견되면 답은 2입니다. 이는 구문 분석된 구문 앞과 뒤의 공백(null인 경우에도)을 나타내고, 응답이 1이면 구문이 구문 분석되지 않았음을 의미합니다.

또한 이 접근 방식을 사용하면 2개 이상의 수준을 설정할 수 있으며 단지 \setsepchar3개 이상의 구문 분석 계층을 설정하는 데만 사용할 수 있습니다.

\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중첩된 s를 통해 프로세스에서 완전히 제거할 수 있습니다 \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를 평가하기 위한 의 첫 번째 인수 내에서 사용할 수 없습니다.
따라서 다른 방법으로 수행해야 합니다. 즉, 세 인수 중 하나를 선택하려면 \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}

관련 정보