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.

7

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

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.