2

I want to save blocks of code/info in a LaTeX file using commands, but I have no way to know how many blocks will be needed. I am wondering if there is a way to create dynamic names of commands so that I can call them later. For example I want something like the following to work:

(Minimal Pseudo Code)

\newcommand{\questionrnd}[1]{
\setcounter{QuestionsForRandomizing}{\arabic{QuestionsForRandomizing}+1}
\newcommand{\QuestionContent\Roman{QuestionsForRandomizing}}{#1}
}

This would take in a block of info (specifically a question, and commands that take in answer choices and randomize them and a variety of other things) and save them in the "next" command. Thus I would end up with commands like \QuestionContentI and \QuestionContentII etc that would contain all the info from questions 1, 2 etc.

Problem being, I can't pregenerate these command names as I have no way of knowing how many questions might be put into the form (this is a CLS file), so I need to create the command (or whatever else would work) dynamically, and then recall them similarly.

I'm giving here a specific example I would like this to work for (saving question content) but I've been trying to figure out a way to store blocks of code dynamically like this for a while, so any general information would help. Ideally the block would need to be able to be executed as LaTeX code itself (meaning all internal function commands still work when the code is called for example).

4

You can create dynamic macro names based on some counter using a combination of techniques. Below you construct the macro name between a \csname...\endcsname primitive:

enter image description here

\documentclass{article}

\newcounter{QuestionsForRandomizing}
\newcommand{\questionrnd}[1]{%
  \stepcounter{QuestionsForRandomizing}%
  \expandafter\newcommand\csname QuestionContent\Roman{QuestionsForRandomizing}\endcsname{#1}%
}

\begin{document}

\questionrnd{abc}\questionrnd{def}%

\verb|\QuestionContentI:| \QuestionContentI

\verb|\QuestionContentII:| \QuestionContentII

\end{document}

The LaTeX kernel also provides \@namedef which implements something similar to the above.

  • This looks like just about exactly what I was looking for, thanks! Can you explain what the \expandafter does? – Jason Oct 16 '15 at 23:19
  • 1
    @Jason: \newcommand expects a control sequence immediately after it. Something like \newcommand\test, so \newcommand\csname test\endcsname won't do, despite the fact that \csname test\endcsname expands to \test. We need to perform the expansion of \csname test\endcsname first, before we can pass it to \newcommand. \expandafter\cmdA\cmdB expands \cmdB first before calling \cmdA. There's some more information here: When to use \edef, \noexpand, and \expandafter? – Werner Oct 16 '15 at 23:23
  • 1
    ...also see A tutorial on \expandafter. – Werner Oct 16 '15 at 23:24
  • Added thanks for the links to the expository info. I usually try to figure this stuff out on my own to learn latex better, but sometimes it's tough even to just find a good explanation of syntax on something I've got no foggy idea about. Appreciate the help, and the additional help, thanks! – Jason Oct 17 '15 at 13:59

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.