1

From this answer I learned how to print rows into 1 column table using pgffor:

| 1 |
| 2 |
| 3 |

Code looks like this:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{pgffor}
\makeatletter
\newtoks\@tabtoks
\newcommand\addtabtoks[1]{\global\@tabtoks\expandafter{\the\@tabtoks#1}}
\newcommand*\resettabtoks{\global\@tabtoks{}}
\newcommand*\printtabtoks{\the\@tabtoks}
\makeatother
\begin{document}
\resettabtoks
\foreach \i in {1,...,3} {%
  \expandafter\addtabtoks\expandafter{\i \\\hline}%
}

\begin{tabular}{ | c | }
  \hline
  \printtabtoks
\end{tabular}
\end{document}

Then I wanted to improve it and get a table with 2 columns:

| 1 | 1 |
| 2 | 2 |
| 3 | 3 |

Using both macro and simple expansion, I created this code:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{pgffor}
\newcommand{\myline}[1]{
  #1 & #1\\ \hline
}
\makeatletter
\newtoks\@tabtoks
\newcommand\addtabtoks[1]{\global\@tabtoks\expandafter{\the\@tabtoks#1}}
\newcommand*\resettabtoks{\global\@tabtoks{}}
\newcommand*\printtabtoks{\the\@tabtoks}
\makeatother
\begin{document}
%1-st attempt
\resettabtoks
\foreach \i in {1,...,3} {%
  \expandafter\addtabtoks\expandafter{\i & \i\\\hline}
}

\begin{tabular}{ | c | c | }
  \hline
  \printtabtoks
\end{tabular}

%2-nd attempt
\resettabtoks
\foreach \i in {1,...,3} {%
  \expandafter\addtabtoks\expandafter{\myline{\i}}
}

\begin{tabular}{ | c | c | }
  \hline
  \printtabtoks
\end{tabular}
\end{document}

1-st attempt gives:

| 1 | l |
| 2 | l |
| 3 | l |

2-nd attempt gives:

| l | l |
| l | l |
| l | l |

Why is "l" shown instead of \i value? And how to fix?

user4035
  • 5,035
  • 6
  • 40
  • 57

2 Answers2

1
 \expandafter\addtabtoks\expandafter{\i & \i\\\hline}

only expands the first \i so you are adding 1&\i then 2&\i then 3&\i so the second column gets the same value at each iteration.

You could use

  \edef\x{\noexpand\addtabtoks{\i & \i\noexpand\\ \noexpand\hline}}
  \x

To fully expand both instances of \i before adding to the token register.

David Carlisle
  • 757,742
1

With the updated code in https://tex.stackexchange.com/a/165149/4035 you can do

\documentclass[10pt,a4paper]{article}
\usepackage{pgffor}

\makeatletter
\newtoks\@tabtoks
%%% assignments to \@tabtoks must be global, because they are done in \foreach
\newcommand\addtabtoks[2][]{%
  \if\relax\detokenize{#1}\relax
    % no index, just append the second argument
    \global\@tabtoks\expandafter{\the\@tabtoks#2}%
  \else
    % we assume the second argument is a one parameter macro
    \global\@tabtoks\expandafter{\the\expandafter\@tabtoks\expandafter#2\expandafter{#1}}%
  \fi
}
%%% variable should always be operated on always locally or always globally
\newcommand*\resettabtoks{\global\@tabtoks{}}
\newcommand*\printtabtoks{\the\@tabtoks}
\makeatother

\newcommand{\myline}[1]{%
  #1 & #1 \\
}


\begin{document}

\resettabtoks
\foreach \i in {1,2,...,5}{%
  \addtabtoks[\i]{\myline}%
}
\begin{tabular}{ | c | c | }
  \hline
  \printtabtoks
  \hline
\end{tabular}

\end{document}

enter image description here

egreg
  • 1,121,712