[Tex/LaTex] How to execute command on every table column

tables

I have a table where I have to execute the same command for every entry in the table. For example:

\ibibleverse{Matthew}(1:1) & \ibibleverse{Mark}(1:1) & \ibibleverse{Luke}(1:1) \\
\ibibleverse{Matthew}(1:2) & \ibibleverse{Mark}(1:2) & \ibibleverse{Luke}(1:2) \\
\ibibleverse{Matthew}(1:3) & \ibibleverse{Mark}(1:3) & \ibibleverse{Luke}(1:3) \etc.

Is there a way that I can make every entry in the column automatically execute the \ibibleverse command so that my table syntax can look like this instead:

1:1 & 1:1 & 1:1 \\
1:2 & 1:2 & 1:2 \\
1:3 & 1:3 & 1:3 \

The parentheses are part of the \ibibleverse command. The full command looks like \ibibleverse{Matthew}(1:1) and outputs "Matthew 1:1".

Of course, the header of the table should not have the \ibibleverse command.

Does this even make sense? Is it possible without repeating, by hand, \ibibleverse so many times?

Best Answer

You can use the collcell package to collect the cell of each row and apply the appropriate macro to the column. Below I defined the columns type W to apply to apply \ibibleverse{Matthew}{#1} macro, K column type to apply \ibibleverse{Mark}{#1}, and the E column type to apply \ibibleverse{Luke}{#1} (column names based on the last characters of Matthew, Mark, and Luke.

enter image description here

Code:

\documentclass{standalone}
\usepackage{collcell}

\newcommand{\ibibleverse}[2]{#1-#2}%

\newcommand{\Matthew}[1]{\ibibleverse{Matthew}{#1}}%
\newcommand{\Mark}[1]{\ibibleverse{Mark}{#1}}%
\newcommand{\Luke}[1]{\ibibleverse{Luke}{#1}}%

\newcommand{\MyCommand}[1]{\textcolor{red}{#1}}

\newcolumntype{W}{>{\collectcell\Matthew}{l}<{\endcollectcell}}
\newcolumntype{K}{>{\collectcell\Mark}{l}<{\endcollectcell}}
\newcolumntype{E}{>{\collectcell\Luke}{l}<{\endcollectcell}}

\begin{document}
\begin{tabular}{W  K  E}
1:1 & 1:1 & 1:1 \\
1:2 & 1:2 & 1:2 \\
1:3 & 1:3 & 1:3 \\
\end{tabular}
\end{document}

If you want to exclude header tows you can use the solution from Tables header row's: how to ignore the column type? to only apply these macros in you are not in a header row.

enter image description here

Code:

\documentclass{standalone}
\usepackage{collcell}
\usepackage{xcolor}%
\usepackage{etoolbox}

\newtoggle{inTableHeader}% Track if still in header of table
\toggletrue{inTableHeader}% Set initial value
\newcommand*{\StartTableHeader}{\global\toggletrue{inTableHeader}}%
\newcommand*{\EndTableHeader}{\global\togglefalse{inTableHeader}}%

% Redefine tabular to initialize \StartTableHeader at start and end
\let\OldTabular\tabular%
\let\OldEndTabular\endtabular%
\renewenvironment{tabular}{\StartTableHeader\OldTabular}{\OldEndTabular\StartTableHeader}%

\newcommand{\ibibleverse}[2]{#1-#2}%

\newcommand{\Matthew}[1]{\iftoggle{inTableHeader}{\textcolor{red}{#1}}{\ibibleverse{Matthew}{#1}}}%
\newcommand{\Mark}[1]{\iftoggle{inTableHeader}{\textcolor{blue}{#1}}{\ibibleverse{Mark}{#1}}}%
\newcommand{\Luke}[1]{\iftoggle{inTableHeader}{\textcolor{brown}{#1}}{\ibibleverse{Luke}{#1}}}%

\newcommand{\MyCommand}[1]{\textcolor{red}{#1}}

\newcolumntype{W}{>{\collectcell\Matthew}{c}<{\endcollectcell}}
\newcolumntype{K}{>{\collectcell\Mark}{c}<{\endcollectcell}}
\newcolumntype{E}{>{\collectcell\Luke}{c}<{\endcollectcell}}

\begin{document}
\begin{tabular}{W  K  E}
Mathew & Mark & Luke \EndTableHeader\\
1:1 & 1:1 & 1:1 \\
1:2 & 1:2 & 1:2 \\
1:3 & 1:3 & 1:3 \\
\end{tabular}
\end{document}
Related Question