2

I need to be able to pass [ ] (brackets with space in between) to a \def and check whether the \def's parameter contains [ ] (rather than something else).

\begin{document}
\def\bptoks{[ ]}
\def\bpdef#1
 { \ifx#1\string\bptoks % DOESN'T WORK
     square brackets
   \else
     something else
   \fi
 }
\bpdef{[ ]} % OUTPUT: something else
\end{document}

EDIT:

\bptoks won't expand at \ifx, so I tried \ifx\detokenize{#1}\detokenize{[ ]} but it's wrong again. I think it's because \ifx checks a single token and I have no clue how to make it check a token list instead. Also, \detokenize{#1} would probably treat #1 as a string (I don't know).

  • 1
    You might also take a look at \@ifnextchar[{true}{false}. – John Kormylo Jul 19 at 14:40
4

\ifx compares two tokens without expansion, so if you pass [ ] to \bpdef, the \ifx test will compare [ with a space and fail. You need to define a temporary macro and compare it with \bptoks. Alternatively you can use \pdfstrcmp (or the equivalent in other engines (\pdf@strcmp if you load pdftexcmds)) to make a string comparison:

\documentclass{article}
\usepackage{pdftexcmds}
\makeatletter
\let\bpstrcmp\pdf@strcmp
\makeatother
\begin{document}
\def\bptoks{[ ]}
\def\bpdef#1%
 {%
   \def\bptmpa{#1}%
   \ifx\bptmpa\bptoks % DOESN'T WORK
     square brackets
   \else
     something else
   \fi
 }
\bpdef{[ ]}\par % OUTPUT: square brackets
\bpdef{] [}\par % OUTPUT: something else
\def\bpdef#1%
 {%
   \ifnum\bpstrcmp{#1}{\bptoks}=0
     square brackets
   \else
     something else
   \fi
 }
\bpdef{[ ]}\par % OUTPUT: square brackets
\bpdef{] [}\par % OUTPUT: something else
\end{document}

Remember also that \ifx compares tokens, not characters, so if you define \bptoks in one catcode setting and change the catcode of either [, , or ] when you use \bpdef, the \ifx test will fail as well. Try this:

\catcode`\[=12
\def\bptoks{[ ]}
\catcode`\[=1
\bpdef{[ ]} % OUTPUT: something else

Additionally, your definition was:

\def\bpdef#1
  { ... }

this is the same as:

\def\bpdef#1 { ... }

which requires that when using the \bpdef macro you must put a space after the first argument, so \bpdef{[]} \par would work, but \bpdef{[]}\par wouldn't. I added a % to remove that.


Regarding the last paragraph in your question: Yes, \ifx does't expand, as I already mentioned, and this implies that when you do \ifx\detokenize{#1}\detokenize{[ ]}, the \ifx compares \detokenize and { and yields false. But no, \detokenize{#1} would acually be \detokenize{<actual-argument>}. The parameter replacement takes place when \bpdef is expanded, and the expansion of \detokenize making #1 (which was already replaced by [ ] or whatever) only happens later on.

2

(This is part 1 of my answer which consists of two parts. Here is a link to part 2 of my answer.)


You can implement such testing by means of delimited arguments also.

With tests based only on delimited arguments, no \if-switches are applied, thus such tests cannot be fooled by unbalanced \else or \fi or \endcsname and the like.

With tests based only on delimited arguments, no temporary assignments take place/no temporary macros get defined while they are carried out. Thus they also work in expansion contexts, i.e., they also work inside \edef or when carried out from within a \csname..\endcsname-construct.

\documentclass{article}

\makeatletter
%%=============================================================================
%% Paraphernalia:
%%    \UD@firstoftwo, \UD@secondoftwo,
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
%%-----------------------------------------------------------------------------
%% 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>
\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}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument contains no exclamation mark which is not nested 
%% in braces:
%%.............................................................................
%% \UD@CheckWhetherNoExclam{<Argument which is to be checked>}%
%%                         {<Tokens to be delivered in case that argument
%%                           contains no exclamation mark>}%
%%                         {<Tokens to be delivered in case that argument
%%                           contains exclamation mark>}%
%%
\newcommand\UD@GobbleToExclam{}\long\def\UD@GobbleToExclam#1!{}%
\newcommand\UD@CheckWhetherNoExclam[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@GobbleToExclam#1!}%
}%
%%-----------------------------------------------------------------------------
%%  \UD@SpaceInBracketsFork grabs the first undelimited argument behind a
%%  token-sequence of pattern  !![ ]! and removes everything between that
%%  undelimited argument and a following sequence !!!! .
%%.............................................................................
\newcommand\UD@SpaceInBracketsFork{}
\long\def\UD@SpaceInBracketsFork#1!![ ]!#2#3!!!!{#2}%
%%-----------------------------------------------------------------------------
%% Check whether argument consists only of the token-sequence [ ]:
%%   In expansion-contexts the check delivers the result after exactly two
%%   expansion-steps/after exactly two "hits" by \expandafter.
%%.............................................................................
\newcommand\UD@CheckWhetherSpaceInBrackets[1]{%
  \romannumeral0% <- romannumeral is used only for triggering expansion until
                %    in the end finding a space token trailing the `0` and thus
                %    finding a non-positive number and thus - after nicely doing
                %    a lot of expansion-work - silently not delivering any token
                %    at all.
  \UD@CheckWhetherNoExclam{#1}{%
    \UD@SpaceInBracketsFork
    %Case #1 is empty/has no tokens:
      !#1![ ]!{\UD@secondoftwo{}{\expandafter} \UD@secondoftwo}%
    %Case #1 = [ ]
      !!#1!{\UD@secondoftwo{}{\expandafter} \UD@firstoftwo}%
    %Case #1 = something else without exclamation-mark:
      !![ ]!{\UD@secondoftwo{}{\expandafter} \UD@secondoftwo}%
      !!!!%
  }{%
    %Case #1 = something else with exclamation-mark:
    \UD@secondoftwo{}{\expandafter} \UD@secondoftwo
  }%
}%
%%-----------------------------------------------------------------------------
\newcommand\bpdef[1]{%
  \UD@CheckWhetherSpaceInBrackets{#1}{square brackets}{something else}%
}%
\makeatother

\begin{document}

1) \verb*|\bpdef{[ ]}|: \bpdef{[ ]}

2) \verb*|\bpdef{ [ ]}|: \bpdef{ [ ]}

3) \verb*|\bpdef{[ ] }|: \bpdef{[ ] }

4) \verb*|\bpdef{ [ ] }|: \bpdef{ [ ] }

5) \verb*|\bpdef{}|: \bpdef{}

6) \verb*|\bpdef{bla}|: \bpdef{bla}

7) \verb*|\bpdef{!![ ]!!!!!!}|: \bpdef{!![ ]!!!!!!}

\end{document}

enter image description here

By the way: Using this kind of thing you can check for several different token sequences simultaneously:

\documentclass{article}

\makeatletter
%%=============================================================================
%% Paraphernalia:
%%    \UD@firstoftwo, \UD@secondoftwo,
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
%%-----------------------------------------------------------------------------
%% 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>
\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}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument contains no exclamation mark which is not nested 
%% in braces:
%%.............................................................................
%% \UD@CheckWhetherNoExclam{<Argument which is to be checked>}%
%%                         {<Tokens to be delivered in case that argument
%%                           contains no exclamation mark>}%
%%                         {<Tokens to be delivered in case that argument
%%                           contains exclamation mark>}%
%%
\newcommand\UD@GobbleToExclam{}\long\def\UD@GobbleToExclam#1!{}%
\newcommand\UD@CheckWhetherNoExclam[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@GobbleToExclam#1!}%
}%
%%-----------------------------------------------------------------------------
%%  \UD@FlowersFork grabs the first undelimited argument behind a
%%  token-sequence of pattern
%%  !!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!
%%  and removes everything between that undelimited argument and a following sequence !!!! .
%%.............................................................................
\newcommand\UD@FlowersFork{}
\long\def\UD@FlowersFork#1!!%
   Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!%
   Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
   #2#3!!!!{#2}%
%%-----------------------------------------------------------------------------
%% Fork whether argument either is empty or is "Rose" or is "Lily" or is "Tulip" 
%% or is "Orchid" or is "Carnation" or is "Hyacinth" or is "Peruvian Lily" or is
%% "Chrysanthemum" or is "Gladiolus" or is "Anemone" or is "Daffodil" or is "Sunflower"
%% or is something else without exclamation-mark or is something else with exclamation-mark.
%%
%%   In expansion-contexts the forking-mechanism delivers the result after exactly two
%%   expansion-steps/after exactly two "hits" by \expandafter.
%%.............................................................................
\newcommand\Flowerfork[1]{%
  \romannumeral0% <- romannumeral is used only for triggering expansion until
                %    in the end finding a space token trailing the `0` and thus
                %    finding a non-positive number and thus - after nicely doing
                %    a lot of expansion-work - silently not delivering any token
                %    at all.
  \UD@CheckWhetherNoExclam{#1}{%
    \UD@FlowersFork
    !#1!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
    { Case: Argument is empty.}%
    !!#1!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
    { Case: Argument is ``Rose''.}%
    !!Rose!#1!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
    { Case: Argument is ``Lily''}%
    !!Rose!Lily!#1!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
    { Case: Argument is ``Tulip''}%
    !!Rose!Lily!Tulip!#1!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
    { Case: Argument is ``Orchid''}%
    !!Rose!Lily!Tulip!Orchid!#1!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
    { Case: Argument is ``Carnation''}%
    !!Rose!Lily!Tulip!Orchid!Carnation!#1!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
    { Case: Argument is ``Hyacinth''}%
    !!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!#1!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
    { Case: Argument is ``Peruvian Lily''}%
    !!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!#1!Gladiolus!Anemone!Daffodil!Sunflower!%
    { Case: Argument is ``Chrysanthemum''}%
    !!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!#1!Anemone!Daffodil!Sunflower!%
    { Case: Argument is ``Gladiolus''}%
    !!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!#1!Daffodil!Sunflower!%
    { Case: Argument is ``Anemone''}%
    !!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!#1!Sunflower!%
    { Case: Argument is ``Daffodil''}%
    !!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!#1!%
    { Case: Argument is ``Sunflower''}%
    !!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
    { Case: Argument is something else which does not contain an exclamation mark.}%
    !!!!%
  }{ %
    Case: Argument is something else which does contain some exclamation mark(s).%
  }%
}%
\makeatother

\begin{document}

01) \verb*|\Flowerfork{Rose}|: \Flowerfork{Rose}%

02) \verb*|\Flowerfork{Lily}|: \Flowerfork{Lily}%

03) \verb*|\Flowerfork{Tulip}|: \Flowerfork{Tulip}%

04) \verb*|\Flowerfork{Orchid}|: \Flowerfork{Orchid}%

05) \verb*|\Flowerfork{Carnation}|: \Flowerfork{Carnation}%

06) \verb*|\Flowerfork{Hyacinth}|: \Flowerfork{Hyacinth}%

07) \verb*|\Flowerfork{Peruvian Lily}|: \Flowerfork{Peruvian Lily}%

08) \verb*|\Flowerfork{Chrysanthemum}|: \Flowerfork{Chrysanthemum}%

09) \verb*|\Flowerfork{Gladiolus}|: \Flowerfork{Gladiolus}%

10) \verb*|\Flowerfork{Anemone}|: \Flowerfork{Anemone}%

11) \verb*|\Flowerfork{Daffodil}|: \Flowerfork{Daffodil}%

12) \verb*|\Flowerfork{Sunflower}|: \Flowerfork{Sunflower}%

13) \verb*|\Flowerfork{Something else without exclamation marks}|: \Flowerfork{Something else without exclamation marks}%

14) \verb*|\Flowerfork{!!Something else with exclamation marks}|: \Flowerfork{!!Something else witht exclamation marks}%

15) \verb*|\Flowerfork{ }|: \Flowerfork{ }%

16) \verb*|\Flowerfork{}|: \Flowerfork{}%

\end{document}

enter image description here


(This is part 1 of my answer which consists of two parts. Here is a link to part 2 of my answer.)

2

(This is part 2 of my answer which consists of two parts. Here is a link to part 1 of my answer.)


By now the tokens that are to be delivered in the different cases were "hardwired" in the macro-definition.

But you can combine such delimited-argument-based forking-mechanisms with mechanisms for grabbing the k-th element of a list of undelimited arguments and thus provide the possibility of specifying the tokens to be delivered in each case by means of a macro argument for each case:

\documentclass[a4paper]{article}

\makeatletter
%%=============================================================================
%% Paraphernalia:
%%    \UD@firstoftwo, \UD@secondoftwo,
%%=============================================================================
\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>
\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. )
%%=============================================================================
%% \KeepKthOfLArguments{<integer number K>}%
%%                     {<integer number L>}%
%%                     <sequence of L consecutive undelimited arguments>
%%
%% If L < 1 yields nothing.
%% Else:
%%   If K >= 1 and K <= L  yields:
%%     <K-th undelimited argument from <sequence of L consecutive undelimited 
%%      arguments>>
%%   If K < 1 or K > L
%%     (-> there is no K-th argument in the
%%         <sequence of L consecutive undelimited arguments> )
%%   yields nothing  but removal of <sequence of L consecutive 
%%          undelimited arguments>
\newcommand\KeepKthOfLArguments[2]{%
  \romannumeral0%
  % #1: <integer number K>
  % #2: <integer number L>
  \expandafter\UD@KeepKthOfLArgumentsKSmallerOneFork
  \expandafter{\romannumeral\number\number#1 000\expandafter}%
  \expandafter{\romannumeral\number\number#2 000}%
}%
%%-----------------------------------------------------------------------------
\newcommand\UD@KeepKthOfLArgumentsKSmallerOneFork[2]{%
  % #1: <K letters m>
  % #2: <L letters m >
  \UD@CheckWhetherNull{#1}{% K is smaller than one:
    \UD@KeepKthOfLArgumentsRemoveNArguments{#2}{ }{}%
  }{% K is not smaller than one:
    \expandafter\UD@PassFirstToSecond
    \expandafter{%
      \UD@firstoftwo{}#1%
    }{%
      \UD@KeepKthOfLArgumentsEvaluateLMinusKDifferenceLoop{#1}{#2}%
    }{#2}%
  }%
}%
%%-----------------------------------------------------------------------------
\newcommand\UD@KeepKthOfLArgumentsEvaluateLMinusKDifferenceLoop[4]{%
  % #1: <K letters m>  
  % #2: <L letters m>
  % (For detecting whether K>L or K<=L, during the loop letters m will
  %  be removed both from #1 and #2 until at least one of these arguments 
  %  is empty.
  %  When the loop terminates with 0<K<=L, #1 will be empty and #2
  %  will hold an amount of letters m corresponding to the the 
  %  difference L-K.
  %  When the loop terminates with K>L, #1 will not be empty and #2
  %  will be empty.
  % )
  % #3: <K-1 letters m>
  % #4: <L letters m>
  % (#3 and #4 will be left untouched during the loop so they can be 
  %  used for performing appropriate action when loop terminates as
  %  it is known whether K>L.)
  \UD@CheckWhetherNull{#1}{% We have K<=L:
     \UD@KeepKthOfLArgumentsRemoveNArguments{%
       #3%
      }{%
       \UD@KeepKthOfLArgumentsRemoveNArguments{#2}{ }%
      }{}%
  }{%
    \UD@CheckWhetherNull{#2}{% We have K>L:
      \UD@KeepKthOfLArgumentsRemoveNArguments{#4}{ }{}%
    }{% We don't know yet whether K<=L or K>L, thus remove letters m and 
      % do another iteration:
      \expandafter\UD@PassFirstToSecond
      \expandafter{%
        \UD@firstoftwo{}#2%
      }{%
        \expandafter\UD@KeepKthOfLArgumentsEvaluateLMinusKDifferenceLoop
        \expandafter{%
          \UD@firstoftwo{}#1%
        }%
      }{#3}{#4}%
    }%
  }%
}%
%%-----------------------------------------------------------------------------
%% \UD@KeepKthOfLArgumentsRemoveNArguments{<N letters m>}%
%%                                        {<argument 1>}%
%%                                        {<argument 2>}%
%%                                        <sequence of consecutive 
%%                                         undelimited arguments>
%%.............................................................................
%% Removes the first N undelimited arguments from the <sequence of 
%% consecutive undelimited arguments>, then inserts  
%% <argument 1><argument 2>
%%
%% On the one hand when providing <argument 2> empty, you can use 
%% <argument 1> for nesting calls to \UD@KeepKthOfLArgumentsRemoveNArguments.
%% On the other hand you can provide a <space token> for stopping
%% \romannumeral-expansion as  <argument 1> and have the
%% macro grab the <K-th undelimited argument> from the <sequence of L 
%% consecutive undelimited arguments> as <argument 2>.
%%
\newcommand\UD@KeepKthOfLArgumentsRemoveNArguments[3]{%
  %% #1: <N letters m>  
  %% #2: <Argument 1>   
  %% #3: <Argument 2>
  \UD@CheckWhetherNull{#1}{#2#3}{%
    \UD@firstoftwo{%
      \expandafter\UD@KeepKthOfLArgumentsRemoveNArguments
      \expandafter{%
        \UD@firstoftwo{}#1%
      }{#2}{#3}%
    }%
  }%
}%
%%-----------------------------------------------------------------------------
%% End of code for \KeepKthOfLArguments.
%%=============================================================================
%% Check whether argument contains no exclamation mark which is not nested 
%% in braces:
%%=============================================================================
%% \UD@CheckWhetherNoExclam{<Argument which is to be checked>}%
%%                         {<Tokens to be delivered in case that argument
%%                           contains no exclamation mark>}%
%%                         {<Tokens to be delivered in case that argument
%%                           contains exclamation mark>}%
%%
\newcommand\UD@GobbleToExclam{}\long\def\UD@GobbleToExclam#1!{}%
\newcommand\UD@CheckWhetherNoExclam[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@GobbleToExclam#1!}%
}%
%%=============================================================================
%% Fork whether argument either is "Rose" or is "Lily" or is "Tulip" or is 
%% "Orchid" or is "Carnation" or is "Hyacinth" or is "Peruvian Lily" or is
%% "Chrysanthemum" or is "Gladiolus" or is "Anemone" or is "Daffodil" or is
%% "Sunflower" or is empty or is something else.
%%
%% \Flowerfork processes 15 arguments. The syntax is:
%%
%% \Flowerfork{<argument to check>}% <- argument 1
%%            {<tokens in case argument is "Rose">}% <- argument 2
%%            {<tokens in case argument is "Lily">}% <- argument 3
%%            {<tokens in case argument is "Tulip">}% <- argument 4
%%            {<tokens in case argument is "Orchid">}% <- argument 5
%%            {<tokens in case argument is "Carnation">}% <- argument 6
%%            {<tokens in case argument is "Hyacinth">}% <- argument 7
%%            {<tokens in case argument is "Peruvian Lily">}% <- argument 8
%%            {<tokens in case argument is "Chrysanthemum">}% <- argument 9
%%            {<tokens in case argument is "Gladiolus">}% <- argument 10
%%            {<tokens in case argument is "Anemone">}% <- argument 11
%%            {<tokens in case argument is "Daffodil">}% <- argument 12
%%            {<tokens in case argument is "Sunflower">}% <- argument 13
%%            {<tokens in case argument is "empty">}% <- argument 14
%%            {<tokens in case argument is something else>}% <- argument 15
%%
%% In expansion-contexts the forking-mechanism delivers the result after exactly
%% two expansion-steps/after exactly two "hits" by \expandafter.
%%=============================================================================
\newcommand\Flowerfork[1]{%
  \romannumeral% <- romannumeral is used only for triggering expansion...
  \expandafter\UD@secondoftwo\KeepKthOfLArguments{%
    \UD@CheckWhetherNoExclam{#1}{%
      \UD@FlowersFork
      !#1!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
      {13}%<-Case: Argument is empty.
      !!#1!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
      {1}%<-Case: Argument is "Rose".
      !!Rose!#1!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
      {2}%<-Case: Argument is "Lily"
      !!Rose!Lily!#1!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
      {3}%<-Case: Argument is "Tulip"
      !!Rose!Lily!Tulip!#1!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
      {4}%<-Case: Argument is "Orchid"
      !!Rose!Lily!Tulip!Orchid!#1!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
      {5}%<-Case: Argument is "Carnation"
      !!Rose!Lily!Tulip!Orchid!Carnation!#1!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
      {6}%<-Case: Argument is "Hyacinth"
      !!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!#1!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
      {7}%<-Case: Argument is "Peruvian Lily"
      !!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!#1!Gladiolus!Anemone!Daffodil!Sunflower!%
      {8}%<-Case: Argument is "Chrysanthemum"
      !!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!#1!Anemone!Daffodil!Sunflower!%
      {9}%<-Case: Argument is "Gladiolus"
      !!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!#1!Daffodil!Sunflower!%
      {10}%<-Case: Argument is "Anemone"
      !!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!#1!Sunflower!%
      {11}%<-Case: Argument is "Daffodil"
      !!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!#1!%
      {12}%<-Case: Argument is "Sunflower"
      !!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
      {14}%<-Case: Argument is something else which does not contain an exclamation mark.
      !!!!%
    }{14}%<-Case: Argument is something else which does contain some exclamation mark(s).%
  }{14}%
}%
%%-----------------------------------------------------------------------------
%%  \UD@FlowersFork grabs the first undelimited argument behind a
%%  token-sequence of pattern
%%  !!Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!
%%  and removes everything between that undelimited argument and a following sequence !!!! .
%%-----------------------------------------------------------------------------
\newcommand\UD@FlowersFork{}
\long\def\UD@FlowersFork#1!!%
   Rose!Lily!Tulip!Orchid!Carnation!Hyacinth!Peruvian Lily!%
   Chrysanthemum!Gladiolus!Anemone!Daffodil!Sunflower!%
   #2#3!!!!{#2}%
\makeatother

% Paper and vertical layout of this example:
\expandafter\ifx\csname pdfpageheight\endcsname\relax\else
  \pdfpageheight=\paperheight
  \pdfpagewidth=\paperwidth
\fi
\expandafter\ifx\csname pageheight\endcsname\relax\else
  \pageheight=\paperheight
  \pagewidth=\paperwidth
\fi
\textheight=\paperheight
\advance\textheight by -5cm
\topmargin=2.5cm
\advance\topmargin by -1in
\headheight=0pt
\headsep=0pt
\footnotesep=1cm
%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

\footnotesize

\begin{verbatim}
\Flowerfork{Lily}%
           {Tokens in case argument is ``Rose''.}%
           {Tokens in case argument is ``Lily''.}%
           {Tokens in case argument is ``Tulip''.}%
           {Tokens in case argument is ``Orchid''.}%
           {Tokens in case argument is ``Carnation''.}%
           {Tokens in case argument is ``Hyacinth''.}%
           {Tokens in case argument is ``Peruvian Lily''.}%
           {Tokens in case argument is ``Chrysanthemum''.}%
           {Tokens in case argument is ``Gladiolus''.}%
           {Tokens in case argument is ``Anemone''.}%
           {Tokens in case argument is ``Daffodil''.}%
           {Tokens in case argument is ``Sunflower''.}%
           {Tokens in case argument is empty.}%
           {Tokens in case argument is something else.}%
\end{verbatim}
yields:
\Flowerfork{Lily}%
           {Tokens in case argument is ``Rose''.}%
           {Tokens in case argument is ``Lily''.}%
           {Tokens in case argument is ``Tulip''.}%
           {Tokens in case argument is ``Orchid''.}%
           {Tokens in case argument is ``Carnation''.}%
           {Tokens in case argument is ``Hyacinth''.}%
           {Tokens in case argument is ``Peruvian Lily''.}%
           {Tokens in case argument is ``Chrysanthemum''.}%
           {Tokens in case argument is ``Gladiolus''.}%
           {Tokens in case argument is ``Anemone''.}%
           {Tokens in case argument is ``Daffodil''.}%
           {Tokens in case argument is ``Sunflower''.}%
           {Tokens in case argument is empty.}%
           {Tokens in case argument is something else.}%

\noindent\null\hrulefill\null

\begin{verbatim}
\Flowerfork{Whatsoever / something else}%
           {Tokens in case argument is ``Rose''.}%
           {Tokens in case argument is ``Lily''.}%
           {Tokens in case argument is ``Tulip''.}%
           {Tokens in case argument is ``Orchid''.}%
           {Tokens in case argument is ``Carnation''.}%
           {Tokens in case argument is ``Hyacinth''.}%
           {Tokens in case argument is ``Peruvian Lily''.}%
           {Tokens in case argument is ``Chrysanthemum''.}%
           {Tokens in case argument is ``Gladiolus''.}%
           {Tokens in case argument is ``Anemone''.}%
           {Tokens in case argument is ``Daffodil''.}%
           {Tokens in case argument is ``Sunflower''.}%
           {Tokens in case argument is empty.}%
           {Tokens in case argument is something else.}%
\end{verbatim}
yields:
\Flowerfork{Whatsoever / something else}%
           {Tokens in case argument is ``Rose''.}%
           {Tokens in case argument is ``Lily''.}%
           {Tokens in case argument is ``Tulip''.}%
           {Tokens in case argument is ``Orchid''.}%
           {Tokens in case argument is ``Carnation''.}%
           {Tokens in case argument is ``Hyacinth''.}%
           {Tokens in case argument is ``Peruvian Lily''.}%
           {Tokens in case argument is ``Chrysanthemum''.}%
           {Tokens in case argument is ``Gladiolus''.}%
           {Tokens in case argument is ``Anemone''.}%
           {Tokens in case argument is ``Daffodil''.}%
           {Tokens in case argument is ``Sunflower''.}%
           {Tokens in case argument is empty.}%
           {Tokens in case argument is something else.}%

\noindent\null\hrulefill\null

\newpage
\begin{verbatim}
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\test
\expandafter\expandafter\expandafter{%
  \Flowerfork{Rose}%
             {Tokens in case argument is ``Rose''.}%
             {Tokens in case argument is ``Lily''.}%
             {Tokens in case argument is ``Tulip''.}%
             {Tokens in case argument is ``Orchid''.}%
             {Tokens in case argument is ``Carnation''.}%
             {Tokens in case argument is ``Hyacinth''.}%
             {Tokens in case argument is ``Peruvian Lily''.}%
             {Tokens in case argument is ``Chrysanthemum''.}%
             {Tokens in case argument is ``Gladiolus''.}%
             {Tokens in case argument is ``Anemone''.}%
             {Tokens in case argument is ``Daffodil''.}%
             {Tokens in case argument is ``Sunflower''.}%
             {Tokens in case argument is empty.}%
             {Tokens in case argument is something else.}%
}%
\end{verbatim}
yields:
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\test
\expandafter\expandafter\expandafter{%
  \Flowerfork{Rose}%
             {Tokens in case argument is ``Rose''.}%
             {Tokens in case argument is ``Lily''.}%
             {Tokens in case argument is ``Tulip''.}%
             {Tokens in case argument is ``Orchid''.}%
             {Tokens in case argument is ``Carnation''.}%
             {Tokens in case argument is ``Hyacinth''.}%
             {Tokens in case argument is ``Peruvian Lily''.}%
             {Tokens in case argument is ``Chrysanthemum''.}%
             {Tokens in case argument is ``Gladiolus''.}%
             {Tokens in case argument is ``Anemone''.}%
             {Tokens in case argument is ``Daffodil''.}%
             {Tokens in case argument is ``Sunflower''.}%
             {Tokens in case argument is empty.}%
             {Tokens in case argument is something else.}%    
}%
\texttt{\string\test: \meaning\test}%

\noindent\null\hrulefill\null

\begin{verbatim}
\newcommand*\MyRoseCommand{This comes from \texttt{\string\MyRoseCommand}.}%
\newcommand*\MyLilyCommand{This comes from \texttt{\string\MyLilyCommand}.}%
\newcommand*\MyTulipCommand{This comes from \texttt{\string\MyTulipCommand}.}%
\newcommand*\MyOrchidCommand{This comes from \texttt{\string\MyOrchidCommand}.}%
\newcommand*\MyCarnationCommand{This comes from \texttt{\string\MyCarnationCommand}.}%
\newcommand*\MyHyacinthCommand{This comes from \texttt{\string\MyHyacinthCommand}.}%
\newcommand*\MyPeruvianLilyCommand{This comes from \texttt{\string\MyPeruvianLilyCommand}.}%
\newcommand*\MyChrysanthemumCommand{This comes from \texttt{\string\MyChrysanthemumCommand}.}%
\newcommand*\MyGladiolusCommand{This comes from \texttt{\string\MyGladiolusCommand}.}%
\newcommand*\MyAnemoneCommand{This comes from \texttt{\string\MyAnemoneCommand}.}%
\newcommand*\MyDaffodilCommand{This comes from \texttt{\string\MyDaffodilCommand}.}%
\newcommand*\MySunflowerCommand{This comes from \texttt{\string\MySunflowerCommand}.}%
\newcommand*\MyEmptyCommand{This comes from \texttt{\string\MyEmptyCommand}.}%
\newcommand*\MySomethingElseCommand{This comes from \texttt{\string\MySomethingElseCommand}.}%
\end{verbatim}

\newcommand*\MyRoseCommand{This comes from \texttt{\string\MyRoseCommand}.}%
\newcommand*\MyLilyCommand{This comes from \texttt{\string\MyLilyCommand}.}%
\newcommand*\MyTulipCommand{This comes from \texttt{\string\MyTulipCommand}.}%
\newcommand*\MyOrchidCommand{This comes from \texttt{\string\MyOrchidCommand}.}%
\newcommand*\MyCarnationCommand{This comes from \texttt{\string\MyCarnationCommand}.}%
\newcommand*\MyHyacinthCommand{This comes from \texttt{\string\MyHyacinthCommand}.}%
\newcommand*\MyPeruvianLilyCommand{This comes from \texttt{\string\MyPeruvianLilyCommand}.}%
\newcommand*\MyChrysanthemumCommand{This comes from \texttt{\string\MyChrysanthemumCommand}.}%
\newcommand*\MyGladiolusCommand{This comes from \texttt{\string\MyGladiolusCommand}.}%
\newcommand*\MyAnemoneCommand{This comes from \texttt{\string\MyAnemoneCommand}.}%
\newcommand*\MyDaffodilCommand{This comes from \texttt{\string\MyDaffodilCommand}.}%
\newcommand*\MySunflowerCommand{This comes from \texttt{\string\MySunflowerCommand}.}%
\newcommand*\MyEmptyCommand{This comes from \texttt{\string\MyEmptyCommand}.}%
\newcommand*\MySomethingElseCommand{This comes from \texttt{\string\MySomethingElseCommand}.}%

\begin{verbatim}
\csname My\Flowerfork{Tulip}%
       {Rose}{Lily}{Tulip}{Orchid}{Carnation}{Hyacinth}{PeruvianLily}{Chrysanthemum}%
       {Gladiolus}{Anemone}{Daffodil}{Sunflower}{Empty}{SomethingElse}Command\endcsname
\end{verbatim}
yields:

\csname My\Flowerfork{Tulip}%
       {Rose}{Lily}{Tulip}{Orchid}{Carnation}{Hyacinth}{PeruvianLily}{Chrysanthemum}%
       {Gladiolus}{Anemone}{Daffodil}{Sunflower}{Empty}{SomethingElse}Command\endcsname

\end{document}

enter image description here

enter image description here


(This is part 2 of my answer which consists of two parts. Here is a link to part 1 of my answer.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.