我经常使用xtring
's\IfStrEqCase
进行条件处理。这很有效,但我想知道是否有一种简单的方法来增强当前行为并允许将多个案例分组为单个匹配。
case 1
在下面的 MWE 中,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}]%
参考:
- 与此主题相关,但有很大不同:概括 \@ifnextchar 以考虑多个字符。。
笔记:
当然,一个解决方案是定义一个宏
\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,表示解析短语前后的空格(即使为空),如果答案为 1,则表示未解析任何短语。
该方法还允许设置 2 个以上的级别,仅用于\setsepchar
设置 3 个或更多层的解析。
\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。
因此,您必须以其他方式执行此操作,即 \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}