3

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.

  • 1
    Welcome to TeX.SX!](meta.tex.stackexchange.com/q/1436) Please help us to help you and add a minimal working example (MWE) that illustrates your problem. It will be much easier for us to reproduce your situation and find out what the issue is when we see compilable code, starting with \documentclass{...} and ending with \end{document}. – user31729 Sep 9 '14 at 8:53
  • I am not sure what you are trying to achieve. Can you express you goal/application in a few sentences? – Johannes_B Sep 9 '14 at 9:14
  • I am not sure, but I believe, this requires to make # inactive for the macro definition – user31729 Sep 9 '14 at 9:21
  • If you are going to iterate over some given list, maybe this would help. By the way, in that case you do not even need to handle the number of arguments. – Symbol 1 Sep 9 '14 at 9:47
  • It's not clear how you'd use this environment; can you make some examples telling what's the supposed output? – egreg Sep 9 '14 at 10:27
5

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

  • Thank you, but can it handle empty spaces? I need the output of \myLocalMacro{ A } to be ' - A - -' In my definition this would have been handled by separating the arguments into {}. And \myLocalMacro{}{A}{} would do the trick. – Václav Pavlík Sep 9 '14 at 12:44

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.