113

Writing (La)TeX code sometimes requires a degree of guile. Here (in no particular order) are two of my favourite examples.

Macros ending with spaces

Pete asked how to see the implementation of \LaTeX, since \show\LaTeX results in \protect \LaTeX. Joseph Wright's suggestion made my day. (I should probably try to get out more).

\let\protect\show
\LaTeX

Uppercasing a variable

I asked how to store the upper case counterpart of a string stored in a variable, because

\def\word{abc}
\def\WORD{\MakeUppercase{\word}}
\show\WORD

returns \MakeUppercase {abc}. Bruno Le Floch offered a superb solution.

\MakeUppercase{\gdef\noexpand\WORD{\word}}

What are your favourite cunning (La)TeX tricks?

Moderator note: this should probably be community wiki.

  • 4
    We should also warn of dangerous uses of primitives and tricks. The implications are not always clear to the neophyte (I too am a novice). I have seen a few dangerous assignments but the following is one type that worries me most: \let\num\m@ne A few commands later the programmer then did \global\advance\num2 This dangerously changes the meaning of \m@ne, as \showthe\m@ne shows. The assignment is dangerous enough without \global. – Ahmed Musa Dec 15 '11 at 17:19
54

This is my killing two birds with one stone technique. Sorting a table and having markdown syntax without catcode changes.

First create a list and a helper macro to add elements.

\let\alist\@empty

\def\addtolist#1#2{%
  \lst@lAddTo#1{#2}}

Create two commands one to sort based on Column A, as a primary index or Column B.

\def\RA#1|#2|#3|#4;{%
  \addtolist{\alist}{#1#2,}%
  \expandafter\gdef\csname#1#2\endcsname{\textit{#1}&#2&#3&#4\cr\relax}
  \lst@BubbleSort{\alist}
}

The sorting macro is from the listings documentation class lstdoc. Data is added as shown below, using the semicolon as an end of line delimiter is a left over from my Pascal days, you can use space if your last column is just numbers or single words.

\RA Lactarius fallax      | velvety milk cap |edible |potentially risky;  
\RA Lactarius camphoratus | candy cap        |edible |aromatic qualities;

In the minimal everything is placed in a box, but it can equally work well using environments or more complicated macros. Change \RA to \RB to sort based on the second column as a primary index.

\documentclass{article}
\usepackage{lstdoc,booktabs}
\begin{document}
\makeatletter
\let\alist\@empty

\def\addtolist#1#2{%
  \lst@lAddTo#1{#2}
}

\def\RA#1|#2|#3|#4;{%
  \addtolist{\alist}{#1#2,}%
  \expandafter\gdef\csname#1#2\endcsname{\textit{#1}&#2&#3&#4\cr\relax}
  \lst@BubbleSort{\alist}
}

\def\RB#1|#2|#3|#4;{%
   \addtolist{\alist}{#2#1,}%
   \expandafter\gdef\csname#2#1\endcsname{\textit{#1}&#2&#3&#4\cr\relax}
   \lst@BubbleSort{\alist}
}

%% adding the data now
\RA Lactarius fallax      | velvety milk cap |edible |potentially risky;  
\RA Lactarius camphoratus | candy cap        |edible |aromatic qualities;
\RA Suillus pungens       | slippery Jack    |edible |poor taste;
\RA Lactarius affinis     | kindred milk     |edible |unpalatable;
\RA Calocybe carnea       | pink fairhead    |edible |potentially risky;
\RA Amateta ocreata       | death angel      |inedible |highly poisonous;   

%% typesetting the table
\newsavebox{\tempbox}
\savebox{\tempbox}{
\centering
\begin{tabular}{llll}
  \toprule[1pt]
  Species & Common name & Edibility & Remarks\\
  \midrule
  \@for\i:=\alist \do{\csname\i\endcsname}
  \vspace{-14pt}\\\bottomrule
\end{tabular}
}

\begin{table}
\usebox{\tempbox}
\caption{Some mushrooms from Wikipedia}
\end{table}
\end{document}

You can add more tricks, depending in what you want to achieve, slightly changing the definition of \RA and \RB you can create automatic links to Wikipedia articles or insert images. This is much quicker than using DBtools and much more flexible.

46
  1. A very useful one is that \romannumeral expands everything on its way until it finds an integer. If the integer is negative, it expands to nothing. This can be used to fully expand something as follows:

    \def\a{\b}\def\b{\c}\def\c{\d}\def\d{1}
    \expandafter\show\romannumeral-`\0\a
    

    Here -`0 is not a complete number (it needs a space to become minus the character code of 0), so TeX looks ahead, expanding tokens as it goes. The code will show 1. On the other hand, \expandafter\show\romannumeral0\a would lead to some surprises: after a few expansions, \a yields 1, and TeX is now seeing \romannumeral01, which will expand to i (or something else if more digits lie ahead). (Thanks egreg for the comment.)

  2. I also like the combination of \afterassignment and \futurelet to read two tokens ahead. For instance,

    \newcommand{\readhead} [2]
      {\afterassignment\@gobble\futurelet#1{#2}}
    

    will set #1 equal to the first token of the list of tokens #2, then remove #2 from the input stream.

  3. Testing if a given token is either -, +, a digit, or something else:

    \newcommand{\test}[1]{%
      \ifcase\numexpr1\noexpand#11\relax
            % -
      \or   % other
      \or   % +
      \else % digit
      \fi}
    

    Replace \noexpand by \string if the goal is to test the character code of a character instead (regardless of category code), assuming that \escapechar is not too crazy.

  4. Test if a character is a letter.

    \ifnum\numexpr\uccode`#1/26=3 True\else False\fi
    

    Of course this breaks if someone plays around with uppercase codes.

  5. Test if a character is a digit.

    \ifnum 9<1#1 True\else False\fi
    
  • So in the first case, does that mean that \romannumeral-`\0 will keep expanding until it hits a space token? – Andrew Stacey Jun 3 '11 at 10:13
  • 1
    @Andrew Until an unexpandable token is found; if this token is a space token, it's ignored. – egreg Jun 3 '11 at 10:48
  • @Bruno Perhaps you can add why -\0 is used instead of a simple 0: in your example if \d` expands to 1, with your construction 1 is found, with \romannumeral0 a surprise would hit the user. – egreg Jun 3 '11 at 10:50
  • @egreg: Interesting. I wonder if that would supply a possible answer to my question: tex.stackexchange.com/q/332/86 – Andrew Stacey Jun 3 '11 at 10:52
  • 9
    I just want to say that I find all of these appalling but fascinating, like quicksand or certain Australian spiders. – Ryan Reich Nov 4 '11 at 17:19
38

One of my favorite kinds of trick is

\begingroup
<assignments>
\def\x{\endgroup<something>}\x

or variations thereof. For example (from the LaTeX kernel)

\begingroup
  \catcode`P=12
  \catcode`T=12
  \lowercase{
    \def\x{\def\rem@pt##1.##2PT{##1\ifnum##2>\z@.##2\fi}}}
  \expandafter\endgroup\x
\def\strip@pt{\expandafter\rem@pt\the}

that could actually be simplified into

\begingroup
  \catcode`P=12
  \catcode`T=12
  \lowercase{\endgroup\def\rem@pt#1.#2PT}{#1\ifnum#2>\z@.#2\fi}
\def\strip@pt{\expandafter\rem@pt\the}

It takes a little bit of thinking to understand how this works. Such uses of \lowercase or \uppercase are abundant in Heiko Oberdiek's packages (which are full of other cunning tricks).

Another variation on the same theme, added after having seen Danie Els's answer. It's not necessary to define globally the active period by saying

\begingroup
  \lccode`\~=`\.
  \lowercase{\endgroup
    \def\unitcenterdot{\mathcode`\.=\string"8000 \def~{\,{\cdot}\,}}}
\protected\def\unit#1{%
    \begingroup\unitcenterdot
        \ensuremath{\mathrm{#1}}%
    \endgroup}
\protected\def\SI#1#2{\ensuremath{#1\,\unit{#2}}}

(the \string is to avoid problems with babel that may activate it). When \lowercase is executed, we have the definition

\def\unitcenterdot{\mathcode`\.=\string"8000 \def.{\,{\cdot}\,}}}

(but where the period is active). In this way we define the meaning of the active period only inside \unit. The commands are defined as robust: there is no problem in having them in arguments of other commands because there's no category code change, but at \write time TeX would find an active period that has no definition.

  • Alas, I am dense - what exactly do these do? – Dean Serenevy Jun 3 '11 at 13:56
  • @Dean: look at Danie Els's answer. With \unit{N.m} you get the correct centered dot. Of course siunitx does the same thing and much more generally. – egreg Jun 3 '11 at 14:00
  • Variation: \begingroup <catcode-assignments> \@firstofone{\endgroup <things to tokenize under different catcode-régime> } – Ulrich Diez Mar 2 at 8:39
36

I like all the catcode changes (do not understand them half the time :-). The following is a very simple function to typeset SI units where a . is made active in math mode and typed as \cdot

{\catcode`\.=13 \gdef.{{\cdot}}}
\newcommand*\unit[1]{%
    \begingroup%
        \mathcode`.="8000%
        \ensuremath{\mathrm{#1}}%
    \endgroup}
\newcommand*\SI[2]{\ensuremath{#1\,\unit{#2}}}

Then the code

\noindent$\unit{N}=\unit{kg.m.s^{-2}}$\qquad \SI{1.2\times10^2}{N.m}

gives

enter image description here

Another great math catcode one is code posted by the late Michael J Downes that will turn -> into shorthand for \rightarrow in math mode.

\makeatletter
\mathchardef\mathminus=\mathcode`\-
\begingroup\catcode`\-=13 \gdef-{\mathhyphen} \endgroup
\def\mathhyphen{\futurelet\foo\mhyphb}
\def\mhyphb{%
    \ifx\foo >\rightarrow \expandafter\@gobble
    \else \mathminus
    \fi}
\mathcode`\-="8000
\makeatother

Then

$x - y$ \qquad $x -> y$

Gives

enter image description here

20

One of my favorite tricks I learned, then stole, from Bruno Le FLoch is \slantbox, as described in his post at Shear transform a "box". This nominally will take an argument and using \pdf... magic, slant it to the right (positive slant) or left (negative slant) to an arbitrary degree.

First, here is Bruno's magic code for your preamble:

\newsavebox{\foobox}
\newcommand{\slantbox}[2][.5]
  {%
    \mbox
      {%
        \sbox{\foobox}{#2}%
        \hskip\wd\foobox
        \pdfsave
        \pdfsetmatrix{1 0 #1 1}%
        \llap{\usebox{\foobox}}%
        \pdfrestore
      }%
  }

Now, just find creative ways to use it. Seems simple enough, but I have found it so versatile, as to use it in many of my answers. For many of them enumerated below, I will provide images.

  1. Provide slant for a font that has no slant: How can I use the slanted variant of the libertine font?

  1. Slant a letter to make it conform to an adjacent object: Victory symbol in Salamanca

  1. Alter a letter slant to better conform with traditional/historical expectations, such as the look of the Laplace transform operator: Is This Laplace Transform Symbol Available in LaTeX?

  1. Drawing boxes that conform to the slant of the italic text: Draw italic box as a placeholder (around a single letter) in a word

  1. Drawing in 3-D perspective: a) Plot 3D stacked squares with shadow, b) How do I display pi in LaTeX like Don?, c) Tikz - Perspective Letter, rotated writing, d) "Star wars" text effect and e) Placing text on face of 3d cube

enter image description here

  1. Simulating left-handed handwriting: Left handed writing

  1. Producing upright greek for any greek font: a) Upright Greek font fitting to Computer Modern and b) Math mode in document title

  1. Creating custom symbols that involve slant: Symbol inbetween "#" and "ff"

  1. Another cunning trick, having absolutely nothing to do with \slantbox, is a simple macro I developed for doing a bubble sort without the use of packages, as shown in this answer, Using LaTeX to compact a list of numbers

The macro itself is

\def\listterminator{9999}% SET TO *ANY* VALUE KNOWN NOT TO BE IN LIST (POSITIVE OR NEGATIVE)
\newcommand\bubblesort[1]{\def\sortedlist{}\sortlist#1,\listterminator,\relax}
\def\sortlist#1,#2,#3\relax{%
  \ifnum#2=\listterminator\relax%
    \edef\sortedlist{\sortedlist#1}%
  \else
    \ifnum#1<#2\relax%
      \edef\sortedlist{\sortedlist#1,}%
      \sortlist#2,#3\relax%
    \else%
      \let\tmp\sortedlist%
      \def\sortedlist{}%
      \expandafter\sortlist\tmp#2,#1,#3\relax%
    \fi%
  \fi%
}

It takes input like \bubblesort{1,2,11, 7, 4, 3} and produces the sorted result in a macro, \sortedlist, to the effect of 1,2, 3, 4, 7,11.

Similar code but fixing two issues of the above bubblesort:

  1. Infinite loop if two values in the list equal. This version drops the duplet.
  2. ! TeX capacity exceeded, sorry [parameter stack size=...] for big lists is fixed.

It also removes the need of the \listterminator by changing the check for the terminating values to an \ifx\undefined#2.

\def\bubblesort#1{\def\sortedlist{}\sortlist#1,\undefined,\relax}
\def\sortlist#1,#2,#3\relax{%
  \ifx\undefined#2%
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {\edef\sortedlist{\sortedlist#1}}
  {%
    \ifnum#1<#2
      \expandafter\@firstoftwo
    \else
      \expandafter\@secondoftwo
    \fi
    {\edef\sortedlist{\sortedlist#1,}\sortlist#2,#3\relax}
    {%
      \ifnum#1=#2
        \expandafter\@firstoftwo
      \else
        \expandafter\@secondoftwo
      \fi
      {\sortlist#2,#3\relax}%
      {%
        \let\tmp\sortedlist
        \def\sortedlist{}%
        \expandafter\sortlist\tmp#2,#1,#3\relax
      }%
    }%
  }%
}
16

Iterating through lists is fairly common and allows for compact code when using an appropriate definition. I often find that dealing with head/tail elements in the list requires special care. Here's an example (using etoolbox, although it holds for most processors/parsers):

enter image description here

\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newcommand{\printlist}[2][,]{%
  \renewcommand*{\do}[1]{#1##1}% How each item is processed
  \docsvlist{#2}}% Process CSV list
\begin{document}
$\printlist{1,2,3,4,5,6,7}$ \par
$\printlist[;]{a,b,c,d,e,f}$
\end{document}

Processing the list in this generic way - placing a delimiter/separator followed by the item - leaves the head with an unwanted delimiter. One way to get rid of this is to define a new delimiter that delays its use for one cycle:

enter image description here

\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newcommand{\printlist}[2][,]{%
  \def\itemdelim{\def\itemdelim{#1}}% Item delimiter delayed by one cycle
  \renewcommand*{\do}[1]{\itemdelim##1}% How each item is processed
  \docsvlist{#2}}% Process CSV list
\begin{document}
$\printlist{1,2,3,4,5,6,7}$ \par
$\printlist[;]{a,b,c,d,e,f}$
\end{document}

At the first cycle and call to \do, \itemdelim redefines itself so that it effectively sets nothing. At subsequent calls to \do, \itemdelim is fully-defined and just sets the delimiter.

Of course, this could be extended to whatever delay you want (not just a single cycle).

The alternative would be do condition on setting the delimiter based on the number of elements up to a certain point. Although intuitive, this is a little more cunning and uses TeX's macro expansion to its advantage.

| improve this answer | |
4

Some tricks:

Instead of

\expandafter\first
\expandafter\second
\expandafter\third
\expandafter\fourth
\expandafter\fifth
\expandafter\sixth
\expandafter\seventh
\expandafter\eighth
\expandafter\ninth
\expandafter\tenth
\eleventh

you can in many situations do:

\newcommand\exchange[2]{#2#1}

\expandafter\exchange\expandafter{\eleventh}{%
   \first\second\third\fourth\fifth\sixth\seventh\eighth\ninth\tenth
}

Instead of

\expandafter\expandafter\expandafter\first
\expandafter\expandafter\expandafter\second
\expandafter\expandafter\expandafter\third
\expandafter\expandafter\expandafter\fourth
\expandafter\expandafter\expandafter\fifth
\expandafter\expandafter\expandafter\sixth
\expandafter\expandafter\expandafter\seventh
\expandafter\expandafter\expandafter\eighth
\expandafter\expandafter\expandafter\ninth
\expandafter\expandafter\expandafter\tenth
\eleventh

you can do:

\newcommand\exchange[2]{#2#1}

\expandafter\first
\expandafter\second
\expandafter\third
\expandafter\fourth
\expandafter\fifth
\expandafter\sixth
\expandafter\seventh
\expandafter\eighth
\expandafter\ninth
\expandafter\tenth
\romannumeral0%
\exchange{ }{\expandafter\expandafter\expandafter}\eleventh

or

\newcommand\exchange[2]{#2#1}

\expandafter\exchange\expandafter{%
  \romannumeral0%
  \exchange{ }{\expandafter\expandafter\expandafter}\eleventh
}{%
  \first\second\third\fourth\fifth\sixth\seventh\eighth\ninth\tenth
}

Assume you wish the second token to be expanded before processing/expanding the first token.

You might do: \expandafter\first\second.

Now assume you wish K-level-expansion of the second token to have taken place before processing/expanding the first token.

With K=1 you can place 1 \expandafter before \first:

\expandafter\first
\second

With K=2 you can place 3 \expandafter before \first:

\expandafter\expandafter
\expandafter\first
\second

With K=3 you can place 7 \expandafter before \first:

\expandafter\expandafter
\expandafter            \expandafter
\expandafter\expandafter
\expandafter            \first
\second

With K=L you can place ∑i=1..L(2L-i)=∑i=1..L(2i-1)=2L-1 \expandafter before \first.

This way the amount of \expandafter that needs to be placed before \first increases exponentially.

Using nested \romannumeral0-expansion, which takes its toll on the semantic nest, you can also have a linear increase of the amount of tokens needed:

\newcommand\exchange[2]{#2#1}%

K=1 - 1-level-expansion of \second shall have taken place before processing/expanding \first:

\expandafter\first
\second

K=2 - 2-level-expansion of \second shall have taken place before processing/expanding \first:

\expandafter\first
\romannumeral0\exchange{ }{\expandafter\expandafter\expandafter}%
\second

K=3 - 3-level-expansion of \second shall have taken place before processing/expanding \first:

\expandafter\first
\romannumeral0\exchange{ }{\expandafter\expandafter\expandafter}%
\romannumeral0\exchange{ }{\expandafter\expandafter\expandafter}%
\second

K=4 - 4-level-expansion of \second shall have taken place before processing/expanding \first:

\expandafter\first
\romannumeral0\exchange{ }{\expandafter\expandafter\expandafter}%
\romannumeral0\exchange{ }{\expandafter\expandafter\expandafter}%
\romannumeral0\exchange{ }{\expandafter\expandafter\expandafter}%
\second

K=5 - 5-level-expansion of \second shall have taken place before processing/expanding \first:

\expandafter\first
\romannumeral0\exchange{ }{\expandafter\expandafter\expandafter}%
\romannumeral0\exchange{ }{\expandafter\expandafter\expandafter}%
\romannumeral0\exchange{ }{\expandafter\expandafter\expandafter}%
\romannumeral0\exchange{ }{\expandafter\expandafter\expandafter}%
\second

K=6 - 6-level-expansion of \second shall have taken place before processing/expanding \first:

\expandafter\first
\romannumeral0\exchange{ }{\expandafter\expandafter\expandafter}%
\romannumeral0\exchange{ }{\expandafter\expandafter\expandafter}%
\romannumeral0\exchange{ }{\expandafter\expandafter\expandafter}%
\romannumeral0\exchange{ }{\expandafter\expandafter\expandafter}%
\romannumeral0\exchange{ }{\expandafter\expandafter\expandafter}%
\second

Get the picture?

For K-level-expansion of \second you need (K-1) instances of
\romannumeral0\exchange{ }{\expandafter\expandafter\expandafter}%
between \expandafter\first and \second.



\expandafter\endcsname-trick:

Assume you have foo and bar and baz and wish to get the sequence \foo\bar\baz, consisting of the tokens \foo and \bar and \baz.
This does the trick:

\csname foo\expandafter\endcsname
\csname bar\expandafter\endcsname
\csname baz\endcsname


Assume you need to construct a control-sequence-token from its name but don't like to combine \csname..\endcsname with "\expandafter-orgies":

Maybe the macro \CsTokenFromCsName is your friend:

\makeatletter
\@ifdefinable\CsTokenFromCsName{%
  \long\def\CsTokenFromCsName#1#{\romannumeral\InnerCsTokenFromCsName{#1}}%
}%
\newcommand\InnerCsTokenFromCsName[2]{%
  \expandafter\exchange\expandafter{\csname#2\endcsname}{0 #1}%
}%
\newcommand\exchange[2]{#2#1}%
\makeatother

\CsTokenFromCsName{foobar}\foobar
\CsTokenFromCsName\newcommand{foobar}...\newcommand\foobar...
\CsTokenFromCsName\global\long\def{foobar}...\global\long\def\foobar...
\CsTokenFromCsName\meaning{foobar}\meaning\foobar
\CsTokenFromCsName\string{foobar}\string\foobar
\CsTokenFromCsName\CsTokenFromCsName\global\let{foo}={bar}
      \CsTokenFromCsName\global\let\foo={bar}
      \global\let\foo=\bar



A nice tool for tail-recursive macros is \PassFirstToSecond, defined as \newcommand\PassFirstToSecond[2]{#2{#1}}:

Assume a tail-recursive macro which calls itself again and again, with modified arguments, until some termination-condition which depends on the tail-recursive macro's arguments is fulfilled.

You can nest calls to \PassFirstToSecond within \PassFirstToSecond's second argument in order to first modify the last argument as needed, then to modify the last but one argument as needed, then to modify the last but two argument as needed, etc.

Can look like this:

\newcommand\TailRecursiveMacro[9]{%
  \if⟨termination-condition that depends on #1..#9 is fulfilled⟩
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {%
    ⟨Things to do with #1..#9 in case termination-condition that depends on #1..#9  is fulfilled⟩%
  }{%
    % Prepare the next iteration as the termination-condition is not fulfilled:
    \expandafter\PassFirstToSecond\expandafter{%
      ⟨Things to do for obtaining the new argument #9, probably a \romannumeral0-expansion-thing⟩%
    }{%
      \expandafter\PassFirstToSecond\expandafter{%
        ⟨Things to do for obtaining the new argument #8, probably a \romannumeral0-expansion- thing⟩%
      }{%
        \expandafter\PassFirstToSecond\expandafter{%
          ⟨Things to do for obtaining the new argument #7, probably a \romannumeral0-expansion- thing⟩%
        }{%
          \expandafter\PassFirstToSecond\expandafter{%
            ⟨Things to do for obtaining the new argument #6, probably a \romannumeral0-expansion-thing⟩%
          }{%
            \expandafter\PassFirstToSecond\expandafter{%
              ⟨Things to do for obtaining the new argument #5, probably a \romannumeral0-expansion-thing⟩%
            }{%
              \expandafter\PassFirstToSecond\expandafter{%
                ⟨Things to do for obtaining the new argument #4, probably a \romannumeral0-expansion-thing⟩%
              }{%
               \expandafter\PassFirstToSecond\expandafter{%
                 ⟨Things to do for obtaining the new argument #3, probably a \romannumeral0-expansion-thing⟩%
                }{%
                  \expandafter\PassFirstToSecond\expandafter{%
                    ⟨Things to do for obtaining the new argument #2, probably a \romannumeral0-expansion-thing⟩%
                  }{%
                    \expandafter\PassFirstToSecond\expandafter{%
                      ⟨Things to do for obtaining the new argument #1, probably a \romannumeral0-expansion-thing⟩%
                    }{%
                      \TailRecursiveMacro
                    }%
                  }%
                }%
              }%
            }%
          }%
        }%
      }%
    }%
  }%
}%

The \romannumeral0-expansion-thingie is mentioned in Bruno Le Floch's answer.

You can combine this with an additional level of \romannumeral-expansion to ensure in expansion-contexts that regardless the amount of iterations the result will always be delivered after two expansion-steps/after two "hits" with \expandafter—can look like this:

\newcommand\TailRecursiveMacro[9]{%
  % Let's start \TailRecursiveMacro's \romannumeral-expansion:
  \romannumeral
  \if⟨termination-condition that depends on #1..#9 is fulfilled⟩
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {%
    % Let's stop  \TailRecursiveMacro's \romannumeral-expansion:
    0⟨space token⟩%
    ⟨Things to do/deliver with #1..#9 in case termination-condition that depends on #1..#9  is fulfilled⟩%
  }{%
    % Prepare the next iteration as the termination-condition is not fulfilled:
    \expandafter\PassFirstToSecond\expandafter{%
      ⟨Things to do for obtaining the new argument #9, probably a \romannumeral0-expansion-thing⟩%
    }{%
      \expandafter\PassFirstToSecond\expandafter{%
        ⟨Things to do for obtaining the new argument #8, probably a \romannumeral0-expansion- thing⟩%
      }{%
        \expandafter\PassFirstToSecond\expandafter{%
          ⟨Things to do for obtaining the new argument #7, probably a \romannumeral0-expansion- thing⟩%
        }{%
          \expandafter\PassFirstToSecond\expandafter{%
            ⟨Things to do for obtaining the new argument #6, probably a \romannumeral0-expansion-thing⟩%
          }{%
            \expandafter\PassFirstToSecond\expandafter{%
              ⟨Things to do for obtaining the new argument #5, probably a \romannumeral0-expansion-thing⟩%
            }{%
              \expandafter\PassFirstToSecond\expandafter{%
                ⟨Things to do for obtaining the new argument #4, probably a \romannumeral0-expansion-thing⟩%
              }{%
               \expandafter\PassFirstToSecond\expandafter{%
                 ⟨Things to do for obtaining the new argument #3, probably a \romannumeral0-expansion-thing⟩%
                }{%
                  \expandafter\PassFirstToSecond\expandafter{%
                    ⟨Things to do for obtaining the new argument #2, probably a \romannumeral0-expansion-thing⟩%
                  }{%
                    \expandafter\PassFirstToSecond\expandafter{%
                      ⟨Things to do for obtaining the new argument #1, probably a \romannumeral0-expansion-thing⟩%
                    }{%
                      % \TailRecursiveMacro's \romannumeral-expansion is already started.
                      % So via \expandafter\@gobble make sure that the next iteration does
                      % not also start \romannumeral-expansion:
                      \expandafter\@gobble\TailRecursiveMacro
                    }%
                  }%
                }%
              }%
            }%
          }%
        }%
      }%
    }%
  }%
}%


You can check whether an argument is empty as follows:

With e-TeX-extensions:

%%=============================================================================
%% Check whether argument is empty:
%%=============================================================================
%% \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>}%
\newcommand\CheckWhetherNull[1]{%
  \romannumeral0\if\relax\detokenize{#1}\relax
  \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
  {\@firstoftwo\expandafter{} \@firstoftwo}%
  {\@firstoftwo\expandafter{} \@secondoftwo}%
}%

Without e-TeX-extensions:

%%=============================================================================
%% Check whether argument is empty:
%%=============================================================================
%% \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\CheckWhetherNull[1]{%
  \romannumeral0\expandafter\@secondoftwo\string{\expandafter
  \@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
  \@secondoftwo\string}\@firstoftwo\expandafter{} \@secondoftwo}%
  {\@firstoftwo\expandafter{} \@firstoftwo}%
}%


You can check whether a macro argument's first token is an explicit catcode-1(begin group)-character-token as follows:

%%-----------------------------------------------------------------------------
%% Check whether argument's first token is an explicit catcode-1-character:
%%.............................................................................
%% \CheckWhetherBrace{<Argument which is to be checked>}%
%%                   {<Tokens to be delivered in case that argument
%%                     which is to be checked has leading
%%                     catcode-1-token>}%
%%                   {<Tokens to be delivered in case that argument
%%                     which is to be checked has no leading
%%                     catcode-1-token>}%
\newcommand\CheckWhetherBrace[1]{%
  \romannumeral0\expandafter\@secondoftwo\expandafter{\expandafter{%
  \string#1.}\expandafter\@firstoftwo\expandafter{\expandafter
  \@secondoftwo\string}\expandafter\expandafter\@firstoftwo{ }{}%
  \@firstoftwo}{\expandafter\expandafter\@firstoftwo{ }{}\@secondoftwo}%
}%


If it is about token-sequences that don't contain curly braces/that do neither contain explicit catcode-1(begin group)-character-tokens, nor contain explicit catcode-2(end group)-character-tokens, then you can check by means of delimited arguments, i.e. by means of expansion only, whether an argument is/is not an element of a set of token-sequences/which element of the set of token-sequences the argument is.

Assume, you wish to check whether an argument either is empty or is A1 or is B2 or is C3 or is D4, and if so, which one it is:

The gist is:

Use a macro with argument-delimiter !!A1!B2!C3!D4! and see where the delimiter-matching takes place.

Of course you first need to ensure that the argument which is to be checked does not contain ! as otherwise the argument which is to be checked might contain the entire delimiter or might in erroneous ways complete the delimiter, which would lead to erroneous delimiter-matching:

\documentclass{article}
\makeatletter
% Use a definition of \CheckWhetherNull as presented above:
\newcommand\CheckWhetherNull[1]{%
  \romannumeral0\if\relax\detokenize{#1}\relax
  \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
  {\@firstoftwo{\expandafter}{} \@firstoftwo}%
  {\@firstoftwo{\expandafter}{} \@secondoftwo}%
}%
\@ifdefinable\GobbletoExclam{\long\def\GobbletoExclam#1!{}}%
\@ifdefinable\Forkfork{\long\def\Forkfork#1!!A1!B2!C3!D4!#2#3!!!!{#2}}%
\newcommand\Fork[7]{%
  % #1 - argument to check
  % #2 - tokens in case Argument is empty
  % #3 - tokens in case Argument is A1
  % #4 - tokens in case Argument is B2
  % #5 - tokens in case Argument is C3
  % #6 - tokens in case Argument is D4
  % #7 - tokens in case Argument is something else
  \expandafter\CheckWhetherNull\expandafter{\GobbletoExclam#1!}{%
    % #1 does not contain "!", so continue testing:
    \Forkfork!#1!A1!B2!C3!D4!{#2}% <- Argument #1 is empty
             !!#1!B2!C3!D4!{#3}% <- Argument #1 is A1
             !!A1!#1!C3!D4!{#4}% <- Argument #1 is B2
             !!A1!B2!#1!D4!{#5}% <- Argument #1 is C3
             !!A1!B2!C3!#1!{#6}% <- Argument #1 is D4
             !!A1!B2!C3!D4!{#7}% <- Argument #1 is something else without "!"
    !!!!%
  }{%
    #7% <- Argument #1 is something else with "!"
  }%

}%
\makeatother

\begin{document}

\Fork{}%
     {You have emptiness.}%
     {You have A1.}%
     {You have B2.}%
     {You have C3.}%
     {You have D4.}%
     {You have something else.}%

\Fork{A1}%
     {You have emptiness.}%
     {You have A1.}%
     {You have B2.}%
     {You have C3.}%
     {You have D4.}%
     {You have something else.}%

\Fork{B2}%
     {You have emptiness.}%
     {You have A1.}%
     {You have B2.}%
     {You have C3.}%
     {You have D4.}%
     {You have something else.}%

\Fork{C3}%
     {You have emptiness.}%
     {You have A1.}%
     {You have B2.}%
     {You have C3.}%
     {You have D4.}%
     {You have something else.}%

\Fork{D4}%
     {You have emptiness.}%
     {You have A1.}%
     {You have B2.}%
     {You have C3.}%
     {You have D4.}%
     {You have something else.}%

\Fork{!A1!B2!C3!D4!}%
     {You have emptiness.}%
     {You have A1.}%
     {You have B2.}%
     {You have C3.}%
     {You have D4.}%
     {You have something else.}%

\Fork{E5}%
     {You have emptiness.}%
     {You have A1.}%
     {You have B2.}%
     {You have C3.}%
     {You have D4.}%
     {You have something else.}%

\end{document}

enter image description here

(Be aware that with the trick above no temporary assignment was performed and no \if..-primitive was used.)


Assume you have a list of L arguments and wish to keep/select only the K-th argument thereof while removing the other arguments from the token-stream.

I can offer the macro \KeepKthOfLArguments:

\documentclass{article}

\makeatletter
%% Code for \KeepKthOfLArguments:
%%=============================================================================
\newcommand\PassFirstToSecond[2]{#2{#1}}%
%%=============================================================================
%% Check whether argument is empty:
%%=============================================================================
%% \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\CheckWhetherNull[1]{%
  \romannumeral0\expandafter\@secondoftwo\string{\expandafter
  \@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
  \@secondoftwo\string}\@firstoftwo\expandafter{} \@secondoftwo}%
  {\@firstoftwo\expandafter{} \@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 >
  \CheckWhetherNull{#1}{% K is smaller than one:
    \UD@KeepKthOfLArgumentsRemoveNArguments{#2}{ }{}%
  }{% K is not smaller than one:
    \expandafter\PassFirstToSecond
    \expandafter{%
      \@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.)
  \CheckWhetherNull{#1}{% We have K<=L:
     \UD@KeepKthOfLArgumentsRemoveNArguments{%
       #3%
      }{%
       \UD@KeepKthOfLArgumentsRemoveNArguments{#2}{ }%
      }{}%
  }{%
    \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\PassFirstToSecond
      \expandafter{%
        \@firstoftwo{}#2%
      }{%
        \expandafter\UD@KeepKthOfLArgumentsEvaluateLMinusKDifferenceLoop
        \expandafter{%
          \@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>
  \CheckWhetherNull{#1}{#2#3}{%
    \@firstoftwo{%
      \expandafter\UD@KeepKthOfLArgumentsRemoveNArguments
      \expandafter{%
        \@firstoftwo{}#1%
      }{#2}{#3}%
    }%
  }%
}%
%%-----------------------------------------------------------------------------
%% End of code for \KeepKthOfLArguments.
\makeatother

\begin{document}

\begin{verbatim}
\KeepKthOfLArguments{17}{30}%
  {Phrase 1}{Phrase 2}{Phrase 3}{Phrase 4}{Phrase 5}{Phrase 6}%
  {Phrase 7}{Phrase 8}{Phrase 9}{Phrase 10}{Phrase 11}{Phrase 12}%
  {Phrase 13}{Phrase 14}{Phrase 15}{Phrase 16}{Phrase 17}{Phrase 18}%
  {Phrase 19}{Phrase 20}{Phrase 21}{Phrase 22}{Phrase 23}{Phrase 24}%
  {Phrase 25}{Phrase 26}{Phrase 27}{Phrase 28}{Phrase 29}{Phrase 30}%
  . Something behind all the phrases.
\end{verbatim}

\KeepKthOfLArguments{17}{30}%
  {Phrase 1}{Phrase 2}{Phrase 3}{Phrase 4}{Phrase 5}{Phrase 6}%
  {Phrase 7}{Phrase 8}{Phrase 9}{Phrase 10}{Phrase 11}{Phrase 12}%
  {Phrase 13}{Phrase 14}{Phrase 15}{Phrase 16}{Phrase 17}{Phrase 18}%
  {Phrase 19}{Phrase 20}{Phrase 21}{Phrase 22}{Phrase 23}{Phrase 24}%
  {Phrase 25}{Phrase 26}{Phrase 27}{Phrase 28}{Phrase 29}{Phrase 30}%
  . Something behind all the phrases.

\bigskip

\noindent\hrulefill

\bigskip

\noindent\verb|\KeepKthOfLArguments| does deliver the result after two
expansion-steps:

\begin{verbatim}
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\test
\expandafter\expandafter\expandafter{%
  \KeepKthOfLArguments{3}{11}{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}%
}%
\end{verbatim}

\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\test
\expandafter\expandafter\expandafter{%
  \KeepKthOfLArguments{3}{11}{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}%
}%

\noindent\texttt{\string\test: \meaning\test}%

\end{document}

enter image description here

(This will be continued in my second answer.)

2

(This is the continuation of my first answer.)

In case you wish to fork/select between more than seven phrases (which with the forking-trick as presented above, where one argument is needed for the thing to check and one argument is used for the "else"-case, would break the nine-argument-limit), you can combine the forking-trick and the select-K-th-of-L-arguments-trick:

\documentclass{article}

\makeatletter
%% Code for \KeepKthOfLArguments:
%%=============================================================================
\newcommand\PassFirstToSecond[2]{#2{#1}}%
%%=============================================================================
%% Check whether argument is empty:
%%=============================================================================
%% \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\CheckWhetherNull[1]{%
  \romannumeral0\expandafter\@secondoftwo\string{\expandafter
  \@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
  \@secondoftwo\string}\@firstoftwo\expandafter{} \@secondoftwo}%
  {\@firstoftwo\expandafter{} \@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 >
  \CheckWhetherNull{#1}{% K is smaller than one:
    \UD@KeepKthOfLArgumentsRemoveNArguments{#2}{ }{}%
  }{% K is not smaller than one:
    \expandafter\PassFirstToSecond
    \expandafter{%
      \@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.)
  \CheckWhetherNull{#1}{% We have K<=L:
     \UD@KeepKthOfLArgumentsRemoveNArguments{%
       #3%
      }{%
       \UD@KeepKthOfLArgumentsRemoveNArguments{#2}{ }%
      }{}%
  }{%
    \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\PassFirstToSecond
      \expandafter{%
        \@firstoftwo{}#2%
      }{%
        \expandafter\UD@KeepKthOfLArgumentsEvaluateLMinusKDifferenceLoop
        \expandafter{%
          \@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>
  \CheckWhetherNull{#1}{#2#3}{%
    \@firstoftwo{%
      \expandafter\UD@KeepKthOfLArgumentsRemoveNArguments
      \expandafter{%
        \@firstoftwo{}#1%
      }{#2}{#3}%
    }%
  }%
}%
%%-----------------------------------------------------------------------------
%% End of code for \KeepKthOfLArguments.

%% Code for forking:
\@ifdefinable\GobbletoExclam{\long\def\GobbletoExclam#1!{}}%
\@ifdefinable\Forkfork{\long\def\Forkfork#1!!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!#2#3!!!!{#2}}%
\newcommand\Fork[1]{%
  % #1 - argument to check
  \KeepKthOfLArguments{%
    % Let's use the \Forkfork-mechanism for obtaining K:
    \expandafter\CheckWhetherNull\expandafter{\GobbletoExclam#1!}{%
      % #1 does not contain "!", so continue testing:
      \Forkfork
      !#1!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{1}% <- Argument #1 is empty
      !!#1!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{2}% <- Argument #1 is AA
      !!AA!#1!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{3}% <- Argument #1 is BB
      !!AA!BB!#1!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{4}% <- Argument #1 is CC
      !!AA!BB!CC!#1!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{5}% <- Argument #1 is DD
      !!AA!BB!CC!DD!#1!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{6}% <- Argument #1 is EE
      !!AA!BB!CC!DD!EE!#1!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{7}% <- Argument #1 is FF
      !!AA!BB!CC!DD!EE!FF!#1!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{8}% <- Argument #1 is GG
      !!AA!BB!CC!DD!EE!FF!GG!#1!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{9}% <- Argument #1 is HH
      !!AA!BB!CC!DD!EE!FF!GG!HH!#1!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{10}% <- Argument #1 is II
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!#1!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{11}% <- Argument #1 is JJ
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!#1!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{12}% <- Argument #1 is KK
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!#1!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{13}% <- Argument #1 is LL
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!#1!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{14}% <- Argument #1 is MM
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!#1!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{15}% <- Argument #1 is NN
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!#1!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{16}% <- Argument #1 is OO
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!#1!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{17}% <- Argument #1 is PP
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!#1!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{18}% <- Argument #1 is QQ
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!#1!SS!TT!UU!VV!WW!XX!YY!ZZ!{19}% <- Argument #1 is RR
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!#1!TT!UU!VV!WW!XX!YY!ZZ!{20}% <- Argument #1 is SS
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!#1!UU!VV!WW!XX!YY!ZZ!{21}% <- Argument #1 is TT
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!#1!VV!WW!XX!YY!ZZ!{22}% <- Argument #1 is UU
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!#1!WW!XX!YY!ZZ!{23}% <- Argument #1 is VV
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!#1!XX!YY!ZZ!{24}% <- Argument #1 is WW
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!#1!YY!ZZ!{25}% <- Argument #1 is XX
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!#1!ZZ!{26}% <- Argument #1 is YY
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!#1!{27}% <- Argument #1 is ZZ
      !!AA!BB!CC!DD!EE!FF!GG!HH!II!JJ!KK!LL!MM!NN!OO!PP!QQ!RR!SS!TT!UU!VV!WW!XX!YY!ZZ!{28}% <- Argument #1 is something else without "!"
      !!!!%
    }{%
      28% <- Argument #1 is something else with "!"
    }%
  }{28}% <- Kth of L with L = 28.
}%
\makeatother

\begin{document}

\Fork{}%
     {You have emptiness.}{You have AA.}{You have BB.}{You have CC.}{You have DD.}{You have EE.}%
     {You have FF.}{You have GG.}{You have HH.}{You have II.}{You have JJ.}{You have KK.}%
     {You have LL.}{You have MM.}{You have NN.}{You have OO.}{You have PP.}{You have QQ.}%
     {You have RR.}{You have SS.}{You have TT.}{You have UU.}{You have VV.}{You have WW.}%
     {You have XX.}{You have YY.}{You have ZZ.}{You have something else.}%

\Fork{HH}%
     {You have emptiness.}{You have AA.}{You have BB.}{You have CC.}{You have DD.}{You have EE.}%
     {You have FF.}{You have GG.}{You have HH.}{You have II.}{You have JJ.}{You have KK.}%
     {You have LL.}{You have MM.}{You have NN.}{You have OO.}{You have PP.}{You have QQ.}%
     {You have RR.}{You have SS.}{You have TT.}{You have UU.}{You have VV.}{You have WW.}%
     {You have XX.}{You have YY.}{You have ZZ.}{You have something else.}%

\Fork{RR}%
     {You have emptiness.}{You have AA.}{You have BB.}{You have CC.}{You have DD.}{You have EE.}%
     {You have FF.}{You have GG.}{You have HH.}{You have II.}{You have JJ.}{You have KK.}%
     {You have LL.}{You have MM.}{You have NN.}{You have OO.}{You have PP.}{You have QQ.}%
     {You have RR.}{You have SS.}{You have TT.}{You have UU.}{You have VV.}{You have WW.}%
     {You have XX.}{You have YY.}{You have ZZ.}{You have something else.}%

\Fork{X?X!}%
     {You have emptiness.}{You have AA.}{You have BB.}{You have CC.}{You have DD.}{You have EE.}%
     {You have FF.}{You have GG.}{You have HH.}{You have II.}{You have JJ.}{You have KK.}%
     {You have LL.}{You have MM.}{You have NN.}{You have OO.}{You have PP.}{You have QQ.}%
     {You have RR.}{You have SS.}{You have TT.}{You have UU.}{You have VV.}{You have WW.}%
     {You have XX.}{You have YY.}{You have ZZ.}{You have something else.}%

\end{document}

enter image description here

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.