7

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}
      \advance\QIternum by 1
      \repeat
    \fi
  }
}

Any help would be greatly appreciated.

Thanks!

  • Welcome to TeX.SX! A tip: You can use backticks ` to mark your inline code. – samcarter_is_at_topanswers.xyz 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? – egreg Aug 16 '16 at 18:11
  • essentially, yes, you are correct – Stephen Strickland Aug 16 '16 at 18:13
  • why the \ifcase rather than simply \renewcommand{\Qinp‌​ut}[1]{\input{foo/C#1.tex}} ? – David Carlisle 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. – Stephen Strickland Aug 16 '16 at 18:17
5

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
    \advance\QIteration\@ne
    \edef\tempb{%
      \expandafter\noexpand\csname or\endcsname
      \noexpand\input{#1/C\the\QIteration.tex}%
    }%
    \expandafter\g@addto@macro\expandafter\tempa\expandafter{\tempb}%
  \repeat
  \g@addto@macro\tempa{\fi}
  \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
    \advance\QIteration\@ne
    \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
| improve this answer | |
7

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
| improve this 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.