How to apply a macro to each column of a table

I want to apply a macro to all the cells of a column with the cell content as the input to the macro. Is this possible?

For example if the cell contents have the word TEST, the macro should take TEST as its argument.

Solutions Collecting From Web of "How to apply a macro to each column of a table"

It should be as simple as:

\def\mymacro#1{\lowercase{#1}}
\halign{&\mymacro{#}\cr
HELLO&WORLD\cr
TEST&123\cr}
\bye

For Yiannis’s comment to apply the macro only to the first column, change the preamble (&\mymacro{#}\cr) to \mymacro{#}&&#\hfil\cr, for example. An ampersand at the very beginning tells TeX to repeat the definition(s) for every column, whereas && defines that the following column definitions should be repeated.

Ofcourse, you don’t need to repeat anything if you don’t want to.

You can use the relatively new collcell package to collect the cell content and feed it to a macro of your choice. It uses the array package to place code before and after each cell.

\documentclass{article}
\usepackage{collcell}
\usepackage{array}% actually already loaded by `collcell`
\newcommand*{\mymacro}[1]{\fbox{#1}}% Do anything you like with `#1`
\newcolumntype{C}{>{\collectcell\mymacro}c<{\endcollectcell}}

\begin{document}

\begin{tabular}{CC}
  TestA  & A longer test cell \\
  \empty & The new version supports 'verb'! \\
\end{tabular}

\end{document}

Make sure you use the version 2011/02/27 (or later) which contains a lot of improvements.

There is also the possibility to do it the following way, which compiles faster than collcell but does not work in the last cell of each row. It reads everything between the internally used macros \ignorespaces and \unskip.
I got this from Ulrike Fischer on de.c.t.t a while ago.

\documentclass{article}
\usepackage{array}
\newcommand*{\mymacro}[1]{\fbox{#1}}

\def\simplecollect#1#2\ignorespaces#3\unskip{#1{#3}\unskip}
\newcolumntype{S}{>{\simplecollect\mymacro}c}

\begin{document}

\begin{tabular}{Sc}
  TestA  & Doesn't work in the last cell \\
  \empty & Sorry!  \\
\end{tabular}

\end{document}

You can do this by using the array package and defining a \newcolumntype.

For example we can define a macro \test that can take a parameter as its argument and capitalize it.

\def\test#1 {\uppercase{#1}}

We can then define a new column type as:

\newcolumntype{D}{>{\test}l<{.}}

and our minimal example would be:

\documentclass{article}
\usepackage{array}
\begin{document}
  \def\test#1 {\uppercase{#1}}
  \newcolumntype{D}{>{\test}l<{.}}
  \begin{tabular}{DD}
    test &test \\
    other &test \\
  \end{tabular}
\end{document}

Please note that this approach involves delimited macros, in this case the space after the word in the table acts to tell the command that it must only read up to there and obviously will fail if there are more than one word as Martin pointed out. One could use other types of delimiters perhaps a . or a !.

Perhaps analogous to @Martin’s answer, you can box the cell contents using an lrbox environment, and then supply the boxed contents to your macro:

enter image description here

\documentclass{article}
\usepackage{array}% http://ctan.org/pkg/array
\begin{document}
\newsavebox{\mybox}
\begin{tabular}{c>{\begin{lrbox}{\mybox}}c<{\end{lrbox}\fbox{\usebox\mybox}}c}
  One & Two & Three \\ \hline
  1 & 2 & 3 \\
  4 & 5 & 6 \\
  7 & 8 & 9 \\ \hline
\end{tabular}
\end{document}

The array package provides the means to insert content before >{...} and after <{...} a specific column. In this case, the lrbox environment start and end, as well as the resulting macro application for typesetting the cell content after boxing.

The restriction is mainly reliant on what can be boxed by the lrbox environment.

EDIT: added support for \multicolumn.

This solution is more or less a LaTeX version of @morbusg’s plain TeX answer. \span forces the expansion of the next token when TeX reads the preamble. \@gobbletwo removes the tokens forming the normal preamble which is inserted by {tabular}: this way, we move the # (i.e. body of the cell) to the middle of what >{...} inserts, rather than after it. More explanations after the code.

\documentclass{article}
\usepackage{array}

\makeatletter
\def\KWP@safe@newline{%
  \iffalse{\fi
  \let\KWP@old@newline\\%
  \let\\\cr
  \iffalse}\fi
}
\def\KWP@restore@newline{\iffalse{\fi\let\\\KWP@old@newline\iffalse}\fi}

\newcolumntype{\arg}[1]{%
  >{\KWP@safe@newline
    #1{\ignorespaces \@sharp\unskip}%
    \KWP@restore@newline
    \span\@gobbletwo}%
  c}

\newcolumntype{\argmulti}[1]{%
  >{\KWP@safe@newline
    #1{\ignorespaces \@sharp\unskip}%
    \KWP@restore@newline
    \@gobbletwo}%
  c}

\makeatother

\begin{document}

First test.
\begin{tabular}{c\arg{\textbf}}
    abc & bcd \\
    cde & def \\
\end{tabular}

\bigskip

\newcommand{\mymacro}[1]{#1: $(#1)^{#1}$}%
Second test.
\begin{tabular}{|\arg{\mymacro}|c|}
    abc & bcd \\
    cdefgh & A\\
    \multicolumn{2}{|c|}{ABC}\\
\end{tabular}

\bigskip

\begin{tabular}{|c|c|}
    abc & bcd \\
    cdefgh & A\\
    \multicolumn{2}{|\argmulti{\mymacro}|}{ABC}\\
\end{tabular}

\end{document}

To give an idea of what’s going on, let’s look at the preamble constructed in the case of the column specification \arg{\textbf}. The “new” part is between \KWP@safe@newline and \@gobbletwo three lines below.

\KWP@safe@newline saves \\, and lets it to \cr. Otherwise, the macro, looking for an argument, would grab everything until the end of the cell, without expanding, and would not see the \cr hidden in the definition of \\. We’ll restore the former definition with \KWP@restore@newline.

\textbf{\ignorespaces \@sharp \unskip} is just our macro. \ignorespaces and \unskip remove spaces from the argument (a better way would trim spaces expandably and pass the argument to \textbf), and \@sharp is let to #, which represents the body of the cell.

Finally, \span\@gobbletwo expands when the preamble is read (i.e., earlier than everything else here), and removes the \@sharp (and \ignorespaces, which I don’t care about).

\@preamble ->\ialign \bgroup \unhcopy \@arstrutbox 
\hskip \col@sep \hfil 
\d@llarbegin 
\KWP@safe@newline 
\textbf {\ignorespaces \@sharp \unskip }%
\KWP@restore@newline 
\span \@gobbletwo \ignorespaces \@sharp \unskip \relax 
\d@llarend 
\hfil \hskip \col@sep 
\tabskip \z@ \cr 

Caveat: if the last column specifier is that \arg, then the last line of the tabular must be terminated with \\ (or \cr or \crcr).