7

I was trying to build a tabular environment that is auto-generated through the use of pgffor's \foreach macro. But I can't seem to get it right.

Here's a MWE for generating a multiplication table:

\documentclass{article}
\usepackage[margin=0.5in,showframe]{geometry}
\usepackage{pgfkeys,pgffor}
%% keys for control the dimensions of the table
\pgfkeys
  {/ae/multiplication/table/.cd,
   xmax/.initial = 9,
   ymax/.initial = 9,
  }
\def\aeget#1{\pgfkeysvalueof{/ae/multiplication/table/#1}}
%% commands to facilitate controlling when expansion occurs.
\def\aemulttable{\tabular[t]}
\def\aecolcnt{{ c | *{\number\numexpr\xmax\relax}{c}}}
\def\mytablecontents{%%'
  \foreach \y in {0,1,...,\ymax} {%%'
    \foreach \x in {0,1,...,\xmax} {%%'
      \ifnum\y=0\relax
        \ifnum\x=0\relax
          $\times$ & %%'
        \else
          $\x$     & %%'
        \fi
      \else
        \ifnum\x=0\relax
          $\y$     & %%'
        \else
          $\number\numexpr\x*\y\relax$ & %%'
        \fi
      \fi
      \ifnum\x=\xmax\relax\\\fi
  }}}

\newcommand{\createtable}[1][]
  {\pgfkeys{/ae/multiplication/table/.cd,#1}%%'
    \def\xmax{\aeget{xmax}}%%'
    \def\ymax{\aeget{ymax}}%%'
    \noindent
    \expandafter\expandafter\expandafter\aemulttable\expandafter\aecolcnt
      \mytablecontents
    \endtabular  
}

\pagestyle{empty}
\begin{document}

\createtable[xmax=4,ymax=25]

\end{document}

I thought Pgffor and the alignment character (&) would be helpful. But the only answer provided does not use pgffor. I have already written my own expl3 solution, but I'd really like to know how to implement this with pgffor.

A.Ellett
  • 50,533
  • I would definitely go with pgfplotstable for this but alternatively, http://tex.stackexchange.com/questions/22275/foreach-inside-a-tikz-matrix , http://tex.stackexchange.com/questions/47595/nested-foreach-inside-a-tikz-matrix-for-both-rows-and-columns out of many others – percusse Aug 09 '13 at 17:52
  • There is a solution at http://sourceforge.net/p/pgf/mailman/message/25630391/ using .aux file. – Boris Bukh Sep 25 '15 at 14:49
  • @BorisBukh Thank you. I'll have to check that out sometime. – A.Ellett Sep 26 '15 at 21:47

1 Answers1

8

Finally got it. After perusing the links suggested by @percusse I finally found the right combination of \expandonce and \noexpand commands to build the contents of a tabular environment within a pgffor \foreach loop.

Here's the working MWE:

\documentclass{article}

\usepackage{pgfkeys}
\usepackage{pgffor}
\usepackage{etoolbox}

\makeatletter
\def\ae@col@max{9}
\def\ae@row@max{9}

\pgfkeys{/ae/multiplication/table/.cd,
  column max/.store in=\ae@col@max,
  row max/.store in=\ae@row@max}

\def\ae@my@tabular{}
\newcommand\ae@build@table{%%
  \let\ae@my@tabular\relax%%
  \foreach \myrow in {0,1,...,\ae@row@max}
  {%%
    \foreach \mycol in {0,1,...,\ae@col@max}
    {%%
      %% first row handled differently                                                     
      %% The first row is a multiplication symbol followed by column headers               
      \ifnum\myrow=0\relax
        \ifx\ae@my@tabular\relax
          \xdef\ae@my@tabular{\noexpand\begin{tabular}{c|*{\number\ae@col@max}{c}}}%%
        \fi
        \ifnum\mycol=0\relax
          \xdef\ae@my@tabular{\expandonce\ae@my@tabular$\times$}%%
        \else
          \xdef\ae@my@tabular{\expandonce\ae@my@tabular & \mycol}
        \fi
      \else
        %% first column handled differently                                                
        %% the first column contains a multiplcaiton symbol or row headers                 
        \ifnum\mycol=0\relax
          \ifnum\myrow=1\relax
            \xdef\ae@my@tabular{\expandonce\ae@my@tabular\noexpand\\\noexpand\hline}%%
          \else
            \xdef\ae@my@tabular{\expandonce\ae@my@tabular\noexpand\\}%%
          \fi
          \xdef\ae@my@tabular{\expandonce\ae@my@tabular \myrow}%%
        \else
          \xdef\ae@my@tabular{\expandonce\ae@my@tabular & \number\numexpr \myrow*\mycol\relax}%%
        \fi
      \fi
    }%%
  }
  \xdef\ae@my@tabular{\expandonce\ae@my@tabular\noexpand\end{tabular}}%%
}

\newcommand\aemultiplicationtable[1][]{%%
  \pgfkeys{/ae/multiplication/table/.cd,#1}%%
  \ae@build@table
  \ae@my@tabular
}

\makeatother
\pagestyle{empty}
\begin{document}

  \aemultiplicationtable[column max=10,row max=15]

\end{document}

which produces:

enter image description here

A.Ellett
  • 50,533