6

I am generating tables from a program and its a bit inconvenient that I have to intersperse style and content information. For example, in the following note how \cellcolor{red} is interspersed among the data. It would be easier to generate if there could be a statement or statements at point %% A or at point %% B in the code below that indicated that in column 3, rows 3-4 that the cells should be colored red. Is this achievable?

\documentclass{article}
\usepackage{colortbl}
\usepackage[table]{xcolor}
\usepackage{tabu}
\begin{document}

\begin{center}
%% A
\begin{tabu}{XXXX}
%% B
1 & 2 & 3 & 4 \\
5 & 6 & 7 & 8 \\
9 & 10 & \cellcolor{red} 11 & 12 \\
13 & 14 & \cellcolor{red} 15 & 16 \\
17 & 18 & 19 & 20 \\
\end{tabu}
\end{center}

\end{document}

Output:

screenshot

By the way, I have already seen this question which is also about separating style and content but as far as I understand it does not really provide the type of solution to the example shown above requested here.

EDIT: In case its not clear here is the type of code that would be desirable:

\documentclass{article}
\usepackage{colortbl}
\usepackage[table]{xcolor}
\usepackage{tabu}
\begin{document}

\begin{center}
\begin{tabu}{XXXX}
\preCell{3}{3}{\cellcolor{red}} % specifies that row 3 col 3 is red
\preCell{4}{3}{\cellcolor{red}} % specifies that row 4 col 3 is red
1 & 2 & 3 & 4 \\
5 & 6 & 7 & 8 \\
9 & 10 & 11 & 12 \\
13 & 14 & 15 & 16 \\
17 & 18 & 19 & 20 \\
\end{tabu}
\end{center}

\end{document}
David Carlisle
  • 757,742
user1189687
  • 1,953
  • In case this is not sufficiently clear I have added some sample code in the EDIT at the end to show the type of TeX code that I would like to generate from the program. Note commented lines in particular. – user1189687 Jul 17 '12 at 12:44

2 Answers2

3

1. All Cells:

If you want all the cells in a particular column to have the same formatting, you can use the collcell package which allows you to pass the entry of each column to a command for further processing:

enter image description here

Alternatively, you could also use the array package, and define:

\newcolumntype{R}{>{\cellcolor{red}}X<{}}

2. Select Cells:

If you only want a select number of cells to be colored then you can use additional commands such as \ActivateColorCell to enable cell coloring and \DectivateColorCell to disable the cell coloring as desired:

enter image description here

Notes:


Code: collcell (all cells):

\documentclass{article}
\usepackage{collcell}
\usepackage{colortbl}
\usepackage[table]{xcolor}
\usepackage{tabu}

\newcommand{\ColorCellRed}[1]{\cellcolor{red}{#1}}

\newcolumntype{R}{>{\collectcell\ColorCellRed}X<{\endcollectcell}}


\begin{document}

\begin{center}
\begin{tabu}{XXRX}
   1 &  2 &  3 &  4 \\
   5 &  6 &  7 &  8 \\
   9 & 10 & 11 & 12 \\
  13 & 14 & 15 & 16 \\
  17 & 18 & 19 & 20 \\
\end{tabu}
\end{center}

\end{document}

Code: array (all cells):

\documentclass{article}
\usepackage{array}
\usepackage{colortbl}
\usepackage[table]{xcolor}
\usepackage{tabu}

\newcolumntype{R}{>{\cellcolor{red}}X<{}}


\begin{document}

\begin{center}
\begin{tabu}{XXRX}
   1 &  2 &  3 &  4 \\
   5 &  6 &  7 &  8 \\
   9 & 10 & 11 & 12 \\
  13 & 14 & 15 & 16 \\
  17 & 18 & 19 & 20 \\
\end{tabu}
\end{center}

\end{document}

Code: collcell (some cells):

\documentclass{article}
\usepackage{collcell}
\usepackage{colortbl}
\usepackage[table]{xcolor}
\usepackage{tabu}
\usepackage{etoolbox}

\newtoggle{EnableColorCell}
\togglefalse{EnableColorCell}

\newcommand*{\ActivateColorCell}{\global\toggletrue{EnableColorCell}}
\newcommand*{\DectivateColorCell}{\global\togglefalse{EnableColorCell}}
\newcommand{\ColorCellRed}[1]{%
    \iftoggle{EnableColorCell}{%
        \cellcolor{red}{#1}%
    }{%
        #1% no cell color as it is disabled
    }%
}

\newcolumntype{R}{>{\collectcell\ColorCellRed}X<{\endcollectcell}}


\begin{document}
\begin{center}
\begin{tabu}{XXRX}
   1 &  2 &  3 &  4 \\
   5 &  6 &  7 &  8 \\\ActivateColorCell
   9 & 10 & 11 & 12 \\
  13 & 14 & 15 & 16 \\\DectivateColorCell
  17 & 18 & 19 & 20 \\
\end{tabu}
\end{center}
\end{document}

Code: array (some cells):

\documentclass{article}
\usepackage{array}
\usepackage{colortbl}
\usepackage[table]{xcolor}
\usepackage{tabu}
\usepackage{etoolbox}

\newtoggle{EnableColorCell}
\togglefalse{EnableColorCell}
\newcommand*{\ActivateColorCell}{\global\toggletrue{EnableColorCell}}
\newcommand*{\DectivateColorCell}{\global\togglefalse{EnableColorCell}}


\newcolumntype{R}{>{\iftoggle{EnableColorCell}{\cellcolor{red}}{}}X<{}}


\begin{document}

\begin{center}
\begin{tabu}{XXRX}
   1 &  2 &  3 &  4 \\
   5 &  6 &  7 &  8 \\\ActivateColorCell
   9 & 10 & 11 & 12 \\
  13 & 14 & 15 & 16 \\\DectivateColorCell
  17 & 18 & 19 & 20 \\
\end{tabu}
\end{center}

\end{document}
Moriambar
  • 11,466
Peter Grill
  • 223,288
  • Thanks but I am looking for the general case so the style does not just affect a column. Regarding the second approach, it intersperses \ActiveateColorCell and \DeactiveColorCello commands with the data whereas they should be separated. The program should be something like: print some text at top; print data; print some text at bottom where all the style info is specified as part of the text at top. – user1189687 Jul 17 '12 at 11:32
1

You can do something like this, but it will probably break as soon as \multicolum is involved:

\documentclass{article}
\usepackage{colortbl}
\usepackage[table]{xcolor}
\usepackage{tabu}
\begin{document}
\makeatletter
\newcommand\preCell[3]{\@namedef{tabstyle-#1-#2}{#3}}
\makeatother
\newcounter{rowcounter}
\newcounter{columncounter}

\begin{center}
\setcounter{rowcounter}{0}
\setcounter{columncounter}{0}

\preCell{3}{3}{\cellcolor{red}} % specifies that row 3 col 3 is red
\preCell{4}{3}{\cellcolor{red}} % specifies that row 4 col 3 is red

\begin{tabu}{>{\stepcounter{rowcounter}%
               \setcounter{columncounter}{0}\stepcounter{columncounter}%
               \csname tabstyle-\therowcounter-\thecolumncounter\endcsname}X
             >{\stepcounter{columncounter}%
              \csname tabstyle-\therowcounter-\thecolumncounter\endcsname}X
             >{\stepcounter{columncounter}%
              \csname tabstyle-\therowcounter-\thecolumncounter\endcsname}X
             >{\stepcounter{columncounter}%
              \csname tabstyle-\therowcounter-\thecolumncounter\endcsname}X}
1 & 2 & 3 & 4 \\
5 & 6 & 7 & 8 \\
9 & 10 & 11 & 12 \\
13 & 14 & 15 & 16 \\
17 & 18 & 19 & 20 \\
\end{tabu}
\end{center}

\end{document}
David Carlisle
  • 757,742
Ulrike Fischer
  • 327,261
  • Excellent. I tried it with two tables in the same document and it still seems to work. I gather than the style info is stored locally in the \begin{center}...\end{center} so that it starts out afresh on any subsequent table. (If you do find any way for it to work with \multicolumn I would also be interested in that as well. – user1189687 Jul 17 '12 at 17:14
  • To get it to work with \multicolumn, you could try to define (witharray`) a new column type which advances the counter correctly and inserts the tabstyle(s) you want to use. – Ulrike Fischer Jul 18 '12 at 08:48