[Tex/LaTex] Use the counter value as an argument

countersenvironment-variablesenvironmentsmacros

Do you know a simple way to use the current counter value to call the argument in a macro?

In myPackage I have this

Note: I have the for loop defined as

% \forloop[step]{counter}{initial_value}{conditional}{code_block}

The problem is in the following code

\newcounter{foo}

\newenvironment{myEnvironment}[1]{
    \newcommand{\myLocalMacro}[#1]{% number of arguments depends on the value inserted in myEnvironment (this works fine)
        \forloop[1]{foo}{1}{\numexpr\value{foo}-1<#1}{
            ##\value{foo} % HERE I need to return ##1 if foo is 1, ##2 if foo is 2 etc. (this doesn't work)
            - % some separator
        }%end forloop
    }%end myLocalMacro
}
{}%end myEnvironment

I tested the variable number of arguments in \myLocalMacro and it works.

I also tested the nesting of arguments in \forloop – writing ##1, ##2 etc. inside the for loop gives 1st and 2nd value. Now I need it dependent on foo counter.

The main document will look like this

\documentclass{article}
\usepackage{myPackage}
\begin{document}

    \begin{myEnvironment}{7}
        \myLocalMacro{F}{O}{O}{B}{A}{R}{1} % this separation into arguments will be written manually
        \myLocalMacro{F}{O}{O}{B}{A}{R}{2}
        \myLocalMacro{F}{O}{O}{B}{A}{R}{3}
    \end{myEnvironment}
    
    or

    \begin{myEnvironment}{3}
        \myLocalMacro{T}{e}{X}
        \myLocalMacro{a}{b}{c}
    \end{myEnvironment}

\end{document}

The expected output should look like

F – O – O – B – A – R – 1 –

F – O – O – B – A – R – 2 –

F – O – O – B – A – R – 3 –

or

T – e – X –

a – b – c –

Well, this is only an example, the real formating will be more complex, which is why I defined an environment for it and don't do it manually for every single character.

Thanks.

Best Answer

Your proposed definition can't work, because TeX makes no expansion to the tokens in the replacement text of a macro and #1 must be literal: it can't be given as #\value{counter}. There are some tricks for making this possible, but I don't think they would help in your case.

Here's something that might be what you're looking for:

\documentclass{article}

\makeatletter
\newenvironment{myEnvironment}[1]
 {\let\myEnv@Temp#1\relax}
 {}

\newcommand\myLocalMacro[1]{%
  \@tfor\next:=#1\do{\expandafter\myEnv@Temp\expandafter{\next}}%
}
\makeatother

\newcommand{\addhyphen}[1]{#1 - }
\newcommand{\addcomma}[1]{#1, }

\begin{document}
\begin{myEnvironment}{\addhyphen}
\myLocalMacro{FOOBAR1}\par
\myLocalMacro{FOOBAR2}\par
\myLocalMacro{FOOBAR3}\par
\end{myEnvironment}

\begin{myEnvironment}{\addcomma}
\myLocalMacro{TeX}\par
\myLocalMacro{abc}\par
\end{myEnvironment}

\end{document}

The argument to myEnvironment is the formatting macro which is applied to every token in the argument to \myLocalMacro.

enter image description here

A different implementation that doesn't require to define auxiliary macros:

\documentclass{article}

\makeatletter
\newenvironment{myEnvironment}[1]
 {\renewcommand\myEnv@Temp[1]{#1}}
 {}

\newcommand\myEnv@Temp{} % initialize

\newcommand\myLocalMacro[1]{%
  \@tfor\next:=#1\do{\expandafter\myEnv@Temp\expandafter{\next}}%
}
\makeatother

\begin{document}
\begin{myEnvironment}{#1 - }
\myLocalMacro{FOOBAR1}\par
\myLocalMacro{FOOBAR2}\par
\myLocalMacro{FOOBAR3}\par
\end{myEnvironment}

\begin{myEnvironment}{#1, }
\myLocalMacro{TeX}\par
\myLocalMacro{abc}\par
\end{myEnvironment}

\end{document}

The argument to myEnvironment is the formatting you want to apply to each token.

If you want to preserve spaces, you need a more complex approach; here's a straightforward way with expl3:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentEnvironment{myEnvironment}{m}
 {
  \cs_set:Nn \pavlik_myenv_temp:n { #1 }
 }
 {
 }

\NewDocumentCommand\myLocalMacro{m}
 {
  \pavlik_myenv_local:n { #1 }
 }

\tl_new:N \l__pavlik_myenv_items_tl

\cs_new_protected:Nn \pavlik_myenv_local:n
 {
  \tl_set:Nn \l__pavlik_myenv_items_tl { #1 }
  \tl_replace_all:Nnn \l__pavlik_myenv_items_tl { ~ } { \c_space_tl } % preserve spaces
  \tl_map_inline:Nn \l__pavlik_myenv_items_tl
   {
    \pavlik_myenv_temp:n { ##1 }
   }
 }
\ExplSyntaxOff

\begin{document}
\begin{myEnvironment}{#1 - }
\myLocalMacro{FOO BAR1}\par
\myLocalMacro{FOOBAR2}\par
\myLocalMacro{FOOBAR3}\par
\end{myEnvironment}

\begin{myEnvironment}{#1, }
\myLocalMacro{TeX}\par
\myLocalMacro{abc}\par
\end{myEnvironment}

\end{document}

Here \tl_map_inline:Nn is the analog of \@tfor; before applying it, we change all spaces in the argument with \c_space_tl, whose expansion is a space.

enter image description here

Related Question