# How to iteratively build \ifcase

Although I've been a LaTeX user for years, this is the first time that I've been unable to find the answer to a LaTeX issue, so this is my first posted question.

I'm defining a command (\QPreparation) that will redefine the command \QInput. The command \QInput{N} should input code into my document based on number N that I send it. With each call of the \QPreparation command, I want the base path \QInput looks in to change as well as the total number of cases that \QInput will consider. The input files are named "C0.tex","C1.tex","C2.tex",... so that in redefining \QInput, the new file options are easy to update.

In the code that I've been working on (below), the 2 inputs to \QPreparation are (a) the base path to update \QInput and (b) the number of cases that I want \QInput to consider.

Because my next step is to modify the \QPreparation command so that the calls \QInput{0}, \QInput{1}, ... \QInput{N} load all N files in a random order, I DO NOT believe that it is feasible to make \QPreparation define \QInput in a manner like \input{#1/C##1.tex}.

If you are curious about how I plan to do the randomization, consider randomize the order of text lines in a .tex file .

It seems to me that the easiest way to solve this problem is to define \QInput with an \ifcase that is generated by a loop. The sample code (below) shows my attempt at this, but the additional \or in the loop throws errors such as:

! Extra \or. \iterate ->\ifnum \the \QIternum <4\relax \or                                                \input {./Q1/C\the \QIternum ....


My sample code:

\newcommand{\QPreparation}[2]{%
\expandafter\renewcommand\csname QInput\endcsname[1]{%
\ifcase##1
\input{#1/C0.tex}
\QIternum=1
\loop\ifnum\the\QIternum<#2\relax
\or
\input{#1/C\the\QIternum.tex}
\repeat
\fi
}
}


Any help would be greatly appreciated.

Thanks!

• Welcome to TeX.SX! A tip: You can use backticks  to mark your inline code. Aug 16 '16 at 17:56
• If I understand your description, after \Qpreparation{foo}{2} the command \Qinput should be defined like in the code \renewcommand{\Qinput}[1]{\ifcase#1\relax \input{foo/C0.tex}\or\input{foo/C1.tex}\or\input{foo/C2.tex}\fi} Am I right? Aug 16 '16 at 18:11
• essentially, yes, you are correct Aug 16 '16 at 18:13
• why the \ifcase rather than simply \renewcommand{\Qinp‌​ut}[1]{\input{foo/C#1.tex}} ? Aug 16 '16 at 18:13
• The code is a work in process, and the next step precludes that simple solution. The next step involves shuffling the file list so that \Qinput{1} will not give \input{fooC1.tex} but instead \input{fooCN.tex} where N is random and determined by the shuffling. I've already found info on how to shuffle'' lines of tex code (see main body of text). If I can make the \ifcase work, then I can reach the goal. Aug 16 '16 at 18:17

The replacement text is not executed when the replacement text is absorbed.

You can build the macro in an indirect way:

\documentclass{article}

\newcommand{\QInput}{} % initialization

\makeatletter
\newcount\QIteration
\newcommand{\QPreparation}[2]{%
\QIteration=\z@
\gdef\tempa{\ifcase####1\relax\input{#1/C0.tex}}%
\loop\ifnum\QIteration<#2
\edef\tempb{%
\expandafter\noexpand\csname or\endcsname
\noexpand\input{#1/C\the\QIteration.tex}%
}%
\repeat
\def\tempb{\renewcommand\QInput[1]}%
\expandafter\tempb\expandafter{\tempa}
}
\makeatother
\QPreparation{foo}{5}

\show\QInput


The \show command will output

> \QInput=\long macro:
#1->\ifcase #1\relax \input {foo/C0.tex}\or \input {foo/C1.tex}\or \input {foo/
C2.tex}\or \input {foo/C3.tex}\or \input {foo/C4.tex}\or \input {foo/C5.tex}\fi
.


which seems to be what you want.

It's necessary to hide \or in the loop, because otherwise we'd get a “misplaced \or” error.

An alternative without global definitions:

\documentclass{article}

\newcommand{\QInput}{} % initialization

\makeatletter
\newcount\QIteration
\toks@={}
\newcommand{\QPreparation}[2]{%
\QIteration=\z@
\toks@={\ifcase##1\relax\input{#1/C0.tex}}%
\loop\ifnum\QIteration<#2
\edef\temp{%
\expandafter\noexpand\csname or\endcsname
\noexpand\input{#1/C\the\QIteration.tex}%
}%
\toks@=\expandafter{\the\expandafter\toks@\temp}%
\repeat
\toks@=\expandafter{\the\toks@\fi}%
\begingroup\edef\x{\endgroup
\noexpand\renewcommand\noexpand\QInput[1]{\the\toks@}%
}\x
}
\makeatother
\QPreparation{foo}{5}

\show\QInput


An equivalent solution if xparse is used:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\tl_new:N \l_strickland_temp_tl
\NewDocumentCommand{\QPreparation}{mm}
{
\tl_clear:N \l_strickland_temp_tl
\int_step_inline:nnnn { 0 } { 1 } { #2 }
{
\tl_put_right:Nn \l_strickland_temp_tl { {##1}{\input{#1/C##1.tex}} }
}
\use:x
{
\exp_not:N \DeclareDocumentCommand \exp_not:N \QInput { m }
{
\exp_not:N \int_case:nn { ####1 } { \exp_not:V \l_strickland_temp_tl }
}
}
}
\ExplSyntaxOff


An alternative way of building up the ifcase

\documentclass{article}

\def\QInput{}
\def\afterfi#1\fi{\fi#1}
\def\QPreparation#1#2{\bgroup
\let\or\relax\let\input\relax
\XQPreparation{#1}{#2}%
\edef\x{\egroup\def\noexpand\QInput####1{%
\noexpand\ifcase####1\relax\input{#1/C0.tex}\QInput\noexpand\fi}}%
\x
}
\def\XQPreparation#1#2{%
\ifnum#2>0 \afterfi
\edef\QInput{\or\input{#1/C#2.tex}\QInput}%
\XQPreparation{#1}{\the\numexpr#2-1\relax}%
\fi}

\begin{document}
\QPreparation{foo}{5}

\show\QInput
\end{document}


produces

> \QInput=macro:
#1->\ifcase #1\relax \input {foo/C0.tex}\or \input {foo/C1.tex}\or \input {foo/
C2.tex}\or \input {foo/C3.tex}\or \input {foo/C4.tex}\or \input {foo/C5.tex}\fi
.
l.23 \show\QInput
`