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.

What may be a neat way of recursively inputting an arbitrary number of rows in a math array? In particular, suppose if I write

\mycommand{A/B, C/D}

then I get

\begin{array}{l} A \mapsto B \\ C \mapsto D\end{array}

whereas if I simply write \mycommand{A/B} then I just get

\begin{array}{l} A \mapsto B \end{array}

I already tried this with

\newcommand*{\mycommand}[1]{ \begin{array}{l} \foreach \xx/\yy in {#1} { \xx \mapsto \yy \\ } \end{array} }

but then I realized, I'm having problems with \\ for each new row.

share|improve this question

2 Answers 2

up vote 5 down vote accepted

You can't process rows with a \foreach cycle in that way. There are two reasons for this:

  1. every cycle is processed in a group
  2. doing it in an array cell can't work anyway, because cells form groups.

Here is an expl3 implementation:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\mycommand}{O{c}m}
 {
  \eric_mycommand:nn { #1 } { #2 }
 }
\tl_new:N \l__eric_array_tl
\cs_new_protected:Npn \eric_mycommand:nn #1 #2
 {
  \tl_clear:N \l__eric_array_tl
  \clist_map_inline:nn { #2 }
   {
    \__eric_process_entry:w ##1 \q_stop
   }
  \begin{array}[#1]{l@{}l}
  \l__eric_array_tl
  \end{array}
 }
\cs_new_protected:Npn \__eric_process_entry:w #1 / #2 \q_stop
 {
  \tl_put_right:Nn \l__eric_array_tl { #1 & {} \mapsto #2 \\ }
 }
\ExplSyntaxOff

\begin{document}

x $\mycommand{A/B}$ y

x $\mycommand[t]{A/B, C/D, E/F}$ y

\bigskip

x $\mycommand{A/B, C/D, E/F}$ y

\end{document}

enter image description here

The optional argument is used for the vertical alignment of the array.


With \foreach you can do like this:

\documentclass{article}
\usepackage{pgffor}

\providecommand{\expandonce}[1]{\unexpanded\expandafter{#1}}

\newcommand\mycommand[1]{%
  \gdef\mycommandtemp{}%
  \foreach \xx/\yy in {#1}{%
    \xdef\mycommandtemp{\expandonce{\mycommandtemp}%
      \expandonce{\xx} & {} \noexpand\mapsto \expandonce{\yy} \noexpand\\}}
  \begin{array}{l@{}l}
    \mycommandtemp
  \end{array}}

\begin{document}

x $\mycommand{A/B}$ y

\bigskip

x $\mycommand{A/B, C/D, E/F}$ y

\end{document}
share|improve this answer
    
This is really good. Thanks! For now I prefer the \foreach code since I understand how it runs. However, I am impressed about the first one on how you thought of the alignment! Thanks! –  Eric Jul 31 '13 at 16:38

An attempt without packages:

(update: this method is quite similar to egreg second one with \foreach and uses a token register rather than a temporary macro; I provide also a second method not doing any assignments, now that I have understood that a \\ just before the final \end{array} is ok, if there is nothing in-between (not even a relax)).

\documentclass{article}

% first method:

\newtoks\ERICtoks
\makeatletter
\newcommand*\ERICarray [1]{\ERICarray@ #1,\ERICarray/,}
\def\ERICarray@  #1/#2,{\ERICtoks={#1\mapsto #2}\ERICarray@@}
\def\ERICarray@@ #1/#2,%
    {\ifx\ERICarray#1\ERICarray@end\else
     \ERICtoks=\expandafter{\the\ERICtoks\\#1\mapsto#2}\fi\ERICarray@@}
\def\ERICarray@end #1\fi\ERICarray@@%
    {\fi\begin{array}{l}\the\ERICtoks\end{array}}
\makeatother

\begin{document}
One line
$\ERICarray{A/B}=
\begin{array}{l}
  A\mapsto B
\end{array}$

Two lines
$\ERICarray{A/B, C/D}=
\begin{array}{l}
  A\mapsto B\\
  C\mapsto D
\end{array}$

Five lines
$\ERICarray{A/B,C/D, E/F,G/H ,  K/L}=
\begin{array}{l}
  A\mapsto B\\ C\mapsto D\\ E\mapsto F\\ G\mapsto H\\ K\mapsto L
\end{array}$
\end{document}

eric arrays

% second method (no assignments, only delimited macros):
\newcommand*\ERICarray [1]{\begin{array}{l}
                           \ERICarrayLOOP #1,\end{array}\ERICarrayCLEANUP/,}
\def\ERICarrayLOOP #1/#2,{#1\mapsto#2\\\ERICarrayLOOP}
\def\ERICarrayCLEANUP\mapsto\\\ERICarrayLOOP{}
share|improve this answer
    
Thank you so much! I don't know how you guys can easily program something like this. I'm jealous! –  Eric Jul 31 '13 at 16:47
    
@Eric I am jealous of egreg too... ;-) and perhaps it is time I learn LaTeX3... (after my vacations, though) –  jfbu Jul 31 '13 at 17:18

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.