Modifizierter \IfStrEqCase mit mehreren Übereinstimmungen pro Fall

Modifizierter \IfStrEqCase mit mehreren Übereinstimmungen pro Fall

Ich verwende häufig xtring's \IfStrEqCasefür die bedingte Verarbeitung. Das funktioniert großartig, aber ich frage mich, ob es eine einfache Möglichkeit gibt, das aktuelle Verhalten zu verbessern und die Gruppierung mehrerer Fälle in einer einzigen Übereinstimmung zu ermöglichen.

Im MWE unten ist die Ausgabe für und identisch, aber ich muss den Text an mehreren Stellen duplizieren. Wenn dieser Text lang ist case 1, ist er ziemlich fehleranfällig, daher wäre es schön, sie alle in einer Syntax wie dieser zusammenfassen zu können: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}]%

Verweise:

Anmerkungen:

  • Eine Lösung wäre natürlich, ein Makro zu definieren

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

    aber ich würde das wenn möglich lieber vermeiden.

Code:

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

Antwort1

Langsam, aber funktioniert. Der Code bearbeitet die Eingabe, um sie für\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}

Bildbeschreibung hier eingeben

Die Verwendung von Variablen kann in folgenden Fällen ermöglicht werden:

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

Antwort2

Hier ist ein listofitemsAnsatz. Der Schlüssel liegt in der Definition des Trennzeichens. Bei Verwendung \setsepchar{case 1||case 3||case 4/case 2||case 5}sucht die Analyse der obersten Ebene nach den Fällen 1, 3 und 4. Die Analyse der zweiten Ebene sucht nach den Fällen 2 und 5. Die Analyse wird mit durchgeführt \readlist\tmp{#1}. Dann \listlen\tmp[]zeigt an, wie viele Elemente durch Aufteilen entlang der Phrase der Analyseebene 1 erstellt werden. Ebenso \listlen\tmp[1]zeigt an, wie viele Elemente durch Aufteilen entlang der Phrase der Analyseebene 2 erstellt werden. Wenn die Phrase gefunden wird, ist die Antwort 2, was das Leerzeichen (auch wenn null) vor und nach der analysierten Phrase angibt, und wenn die Antwort 1 ist, bedeutet dies, dass keine Phrase analysiert wurde.

Der Ansatz ermöglicht auch die Festlegung von mehr als zwei Ebenen, d. h. lediglich \setsepchardie Festlegung von drei oder mehr Analyseebenen.

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

Bildbeschreibung hier eingeben

Natürlich xstringkann durch verschachtelte \ifnums vollständig aus dem Prozess eliminiert werden:

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

URSPRÜNGLICHE ANTWORT

Warum definieren Sie sie nicht einfach \msgAund \msgBverweisen indirekt von Fall zu Fall darauf? Dadurch wird vermieden, dass dieselbe Nachricht mehrmals neu eingegeben werden muss.

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

Antwort3

Vor einigen Jahren habe ich eine Routine geschrieben \UD@KeepKthOfLArguments, mit der Sie aus einer beliebigen Anzahl von unbegrenzten Argumenten ein beliebiges unbegrenztes Argument auswählen können, das – aufgrund der Rekursion – nicht an die 9-Argument-Begrenzung gebunden ist, die normalerweise der Makroprogrammierung von TeX auferlegt wird.

Leider ist es selbst nicht vollständig erweiterbar und kann daher nicht innerhalb des ersten Arguments zur Berechnung der Zahl K \IfStrEqCaseverwendet werden . Daher müssen Sie es andersherum machen, d. h. von innen aufrufen , um eines der drei Argumente auszuwählen:\UD@KeepKthOfLArguments
\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}

Übrigens: Falls Sie eine solche Auswahl in reinen Erweiterungskontexten treffen möchten, finden Sie hier ein Beispiel für eine Strategie, die auf der Verwendung abgegrenzter Argumente basiert:

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

verwandte Informationen