I have commands called \cta, \ctb, ctc, \ctd.
I'd like to call these commands from within a loop, as follows:
\foreach \i in {a,b,c,d}{
% this is where I want to call the command
}
How can I achieve this?
The TeX primitives \csname...\endcsname allow to construct macro names.
\documentclass{article}
\usepackage{tikz}
\newcommand{\cta}{A}
\newcommand{\ctb}{BB}
\newcommand{\ctc}{CCC}
\newcommand{\ctd}{DDDD}
\begin{document}
\foreach \i in {a,b,c,d}{The content of \texttt{\expandafter\string\csname ct\i\endcsname} is \csname ct\i\endcsname.\par}
\end{document}
When TeX encounters
\csname ct\i\endcsname
it expands \i (and it keeps expanding) until only character tokens are obtained, and builds a control sequence with the corresponding "string". (An error is thrown if the expansion produces a non-character token.)
\endlinechar is taken into consideration, the expandable \input-primitive can be used inside \csname..\endcsname, thus: Additionally to egreg's comment: For example a control-sequence defined in terms of \toksdef is neither a primitive nor expandable but leads to an error-message inside \csname..\endcsname unless preceded by \the. Errors are also thrown in case of characters of category code 15 occurring in the .tex-input. ;-)
– Ulrich Diez
Jul 30 '20 at 09:08
A fairly general loop:
documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\loopvar}{m +O{} m +O{}}
{
\clist_map_inline:nn { #3 } { #2 \use:c { #1##1 } #4 }
}
\ExplSyntaxOff
\newcommand{\cta}{\texttt{\string\cta}}
\newcommand{\ctb}{\texttt{\string\ctb}}
\newcommand{\ctc}{\texttt{\string\ctc}}
\newcommand{\ctd}{\texttt{\string\ctd}}
\begin{document}
\loopvar{ct}{a,b,c,d}
\loopvar{ct}[This is ]{a,b,c}[\par]
\end{document}
The first mandatory argument is the common part, the second mandatory argument is the list of strings to append; the first optional argument is a “prefix” to add before the macro, the traling one is the “postfix”.
Explanation: \use:c builds a control sequence name from its argument and is essentially \csname...\endcsname in disguise; \clist_map_inline:nn maps the comma separated list executing for each item the code specified in the second argument (#1 stands for the current item, but here we need to use ##1 because we're defining a macro).
As in TeX everything is about tokens that might be expandable, you are faced with the question about the order in time in which expansion of \cta, \ctb, \ctc, \ctd shall take place.
Case 1:
Is the loop to deliver the entire token-sequence \cta\ctb\ctc\ctd ?
(In case \cta is a macro that processes three non-delimited arguments, its first argument is the token \ctb, its second argument is the token \ctc and its third argument is the token \ctd.)
Case 2:
Is the token \cta to be produced and expanded totally and carried out completely in the first iteration, then the token \ctb to be produced and expanded totally and carried out completely in the second iteration, then the token \ctc to be produced and expanded totally and carried out completely in the third iteration, then the token \ctd to be produced and expanded totally and carried out completely in the fourth iteration?
How to do the second case has already been shown by campa and egreg.
So let's focus on the first case:
You could use a scratch-macro for accumulating tokens:
\documentclass{article}
\usepackage{tikz}
\newcommand*{\cta}[3]{%
\noindent
\texttt{\string\cta}'s first argument is: \texttt{\string#1}\%
\texttt{\string\cta}'s second argument is: \texttt{\string#2}\%
\texttt{\string\cta}'s third argument is: \texttt{\string#3}%
\bigskip
#1#2#3%
}
\newcommand*{\ctb}[2]{%
\noindent
\texttt{\string\ctb}'s first argument is: \texttt{\string#1}\%
\texttt{\string\ctb}'s second argument is: \texttt{\string#2}%
\bigskip
#1#2%
}
\newcommand*{\ctc}[1]{%
\noindent
\texttt{\string\ctc}'s first argument is: \texttt{\string#1}%
\bigskip
#1%
}
\newcommand*{\ctd}{%
\noindent
\texttt{\string\ctd} does not process arguments.%
}
\newcommand\scratchmacro{}%
\begin{document}
\def\scratchmacro{}
\foreach \i in {a,b,c,d}{%
\csname g@addto@macro%
\expandafter\endcsname
\expandafter{%
\expandafter\scratchmacro
\expandafter}%
\expandafter{%
\csname ct\i\endcsname
}%
}%
\noindent
\texttt{\string\scratchmacro: \meaning\scratchmacro}
\bigskip
\scratchmacro
\end{document}
If you wish a fully expandable loop, then you are faced with the task of expandable comma-list-parsing.
In this case you might be interested in the answers to the question \newcommand with many arguments.
If you wish a fully expandable loop, but can make it with a list of non-delimited arguments instead of a comma-list, i.e., something like {a}{b}{c}{d} instead of a,b,c,d, then you are faced with the task of expandable argument-list-parsing.
In this case you might be interested in some of the answers to the question defining a new command with variable name in a loop.
Another approach could be:
\documentclass{article}
\makeatletter
\newcommand\UD@exchange[2]{#2#1}%
\newcommand\nameloop{\romannumeral0\UD@innernameloop}%
\newcommand\UD@innernameloop[3]{%
\ifx\relax#3\expandafter@firstoftwo\else\expandafter@secondoftwo\fi
{ #2}{%
\expandafter\UD@exchange
\expandafter{%
\expandafter{%
\romannumeral0%
\expandafter\UD@exchange\expandafter{%
\csname#1#3\endcsname
}{ #2}%
}}{%
\UD@innernameloop{#1}%
}%
}%
}%
\makeatother
\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\scratchmacro
\expandafter\expandafter\expandafter{%
\nameloop{ct}{Tokens in front}{a}{b}{c}{d}{\relax}%
}%
\begin{document}
\texttt{\string\scratchmacro: \meaning\scratchmacro}
\end{document}
\cta, \ctb, \ctc, \ctd.(with punctuation) or just\cta\ctb\ctc\ctd? – egreg Jul 30 '20 at 08:29\ctawithout punctuation. There are four commands in total (although of course the number doesn't matter as I could loop as many as I wanted). – Thev Jul 30 '20 at 08:33