Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I have a macro (say \myMacro) that takes three arguments (say a, b, c) and I want to write another macro (say \otherMacro) that given three lists of parameters (comma delimited lists and all of the same length and the length of the lists is two or more) maps \myMacro onto these arguments in turn. That is

\otherMacro {a1, a2, a3}{b1, b2, b3}{c1, c2, c3}

gives the representation

\myMacro{a1}{b1}{c1} \mapsto
  (\myMacro{a2}{b2}{c2} , \myMacro{a3}{b3}{c3})

and

\otherMacro {a1, a2, a3, a4}{b1, b2, b3, b4}{c1, c2, c3, c4}

gives the representation

\myMacro{a1}{b1}{c1} \mapsto
  (\myMacro{a2}{b2}{c2} , \myMacro{a3}{b3}{c3}, \myMacro{a4}{b4}{c4})

I am a LaTeX novice and I am very sorry if similar questions have already been asked. I searched the site and found problems that were somewhat similar but I couldn't make sense of the solutions.

share|improve this question
add comment

2 Answers

up vote 5 down vote accepted

A rather crude version:

\documentclass{article}

\makeatletter
\newcount\my@index
\newcommand\otherMacro[3]
{%
  \my@index\z@
  \@othermacro#1,\@nil#2,\@nil#3,\@nil
}
\def\@othermacro#1,#2\@nil#3,#4\@nil#5,#6\@nil
{%
  \ifnum\my@index=\@ne\mapsto (\fi
  \ifnum\my@index>\@ne,\fi
  \myMacro{#1}{#3}{#5}%
  \ifx\empty#2\empty
    )%
   \else
    \advance\my@index\@ne
    \@othermacro#2\@nil#4\@nil#6\@nil
  \fi
}
\newcommand\myMacro[3]{\max(#1,#2,#3)}
\makeatother

\begin{document}

$\otherMacro {a1,a2,a3,a4}{b1,b2,b3,b4}{c1,c2,c3,c4}$


\end{document}
share|improve this answer
    
Works perfectly. Thank you so much! –  A R Mar 26 '12 at 15:18
    
In that case you could accept the answer. –  Stephan Lehmke Mar 26 '12 at 15:18
    
@stephen-lehmke Thank you again. I had never seen this syntax before (e.g. \@ne, \my@index, etc.) I was wondering if you could tell me where I can read more about this? –  A R Mar 26 '12 at 16:15
    
In principle you'll find all you need to know in the TeXbook by Donald E. Knuth. The macro names with @ in them are not a special "notation" though but just a convention for writing "internal" macro or counter names. Normally @ is not a letter, so names with @ in them can not be used. In packages, this is allowed, or if it is explicitly turned on (as I did) with \makeatletter. \@ne is simply a predefined name denoting "1". –  Stephan Lehmke Mar 26 '12 at 16:20
add comment

This works for arbitrarily long lists (at least two elements, of course):

\documentclass{article}
\usepackage{xparse}

\newcommand{\myMacro}[3]{[#1,#2,#3]} % define suitably

\ExplSyntaxOn
\NewDocumentCommand{\otherMacro}{mmm}{ \maps_splitargs:nnn {#1}{#2}{#3} }

\seq_new:N \l_maps_first_seq
\seq_new:N \l_maps_second_seq
\seq_new:N \l_maps_third_seq

\cs_new:Npn \maps_splitargs:nnn #1 #2 #3
 {
  \seq_set_split:Nnn \l_maps_first_seq  {,} { #1 }
  \seq_set_split:Nnn \l_maps_second_seq {,} { #2 }
  \seq_set_split:Nnn \l_maps_third_seq  {,} { #3 }
  \prg_stepwise_inline:nnnn { 0 } { 1 } { \seq_length:N \l_maps_first_seq - 1 }
   {
    \tl_set:Nx \l_tmpa_tl
     {
      { \seq_item:Nn \l_maps_first_seq { ##1 } }
      { \seq_item:Nn \l_maps_second_seq { ##1 } }
      { \seq_item:Nn \l_maps_third_seq { ##1 } }
     }
    \exp_after:wN \myMacro \l_tmpa_tl
    \int_compare:nTF { ##1 = 0 }
     { \mapsto ( }
     { \int_compare:nTF { ##1 = \seq_length:N \l_maps_first_seq - 1 } { ) } { , } }
   }
 }
\ExplSyntaxOff


\begin{document}

$\otherMacro {a1,a2}{b1,b2}{c1,c2}$

$\otherMacro {a1,a2,a3}{b1,b2,b3}{c1,c2,c3}$

$\otherMacro {a1,a2,a3,a4}{b1,b2,b3,b4}{c1,c2,c3,c4}$

$\otherMacro {a1,a2,a3,a4,a5}{b1,b2,b3,b4,b5}{c1,c2,c3,c4,c5}$

\end{document}

Important change

Due to the changes made to expl3 in Summer 2012, the code above should be replaced by the following:

\documentclass{article}
\usepackage{xparse}

\newcommand{\myMacro}[3]{[#1,#2,#3]} % define suitably

\ExplSyntaxOn
\NewDocumentCommand{\otherMacro}{mmm}{ \maps_splitargs:nnn {#1}{#2}{#3} }

\seq_new:N \l_maps_first_seq
\seq_new:N \l_maps_second_seq
\seq_new:N \l_maps_third_seq

\cs_new:Npn \maps_splitargs:nnn #1 #2 #3
 {
  \seq_set_split:Nnn \l_maps_first_seq  {,} { #1 }
  \seq_set_split:Nnn \l_maps_second_seq {,} { #2 }
  \seq_set_split:Nnn \l_maps_third_seq  {,} { #3 }
  \int_step_inline:nnnn { 1 } { 1 } { \seq_count:N \l_maps_first_seq }
   {
    \tl_set:Nx \l_tmpa_tl
     {
      { \seq_item:Nn \l_maps_first_seq { ##1 } }
      { \seq_item:Nn \l_maps_second_seq { ##1 } }
      { \seq_item:Nn \l_maps_third_seq { ##1 } }
     }
    \exp_after:wN \myMacro \l_tmpa_tl
    \int_compare:nTF { ##1 = 1 }
     { \mapsto ( }
     { \int_compare:nTF { ##1 = \seq_count:N \l_maps_first_seq } { ) } { , } }
   }
 }
\ExplSyntaxOff


\begin{document}

$\otherMacro {a1,a2}{b1,b2}{c1,c2}$

$\otherMacro {a1,a2,a3}{b1,b2,b3}{c1,c2,c3}$

$\otherMacro {a1,a2,a3,a4}{b1,b2,b3,b4}{c1,c2,c3,c4}$

$\otherMacro {a1,a2,a3,a4,a5}{b1,b2,b3,b4,b5}{c1,c2,c3,c4,c5}$

\end{document}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.