I would like to define appropriate column types which suppress an entire row of a table if all of the columns (besides the title column, ie the first column) are empty. That is, with the tabular
content as:
Label 1 & 62 & 79 \\
Label 2 & & \\
Label 3 & & 31 \\
Label 4 & 45 & \\
I would like to automatically suppress the row with Label 2
.
My Attempt:
I defined a T
column type at which time it is determined if the prior row is to be typeset via:
\newcommand{\TitleColumn}[1]{% We are starting a new row
%% If there was a previous row that needed to be output, display that now
\iftoggle{DisplayThisRow}{%
\PrintTableTokens% Print prior row
\global\togglefalse{DisplayThisRow}% Assume entire row is empty
}{%
%\vspace*{-\baselineskip}% Attempt to fix empty rows.
}%
\ResetTableTokens%
\AddTableTokens{#1}% Start a new row with the row label
}
All other columns are of type L
which sets the boolean DisplayThisRow
to true
upon encountering a non-empty cell:
\newcommand{\ColumnL}[1]{%
\AddTableTokens{#1}% <--- Need a leading & here
\IfStrEq{#1}{}{}{% Enable printing of row if non-empty content encoutered
\global\toggletrue{DisplayThisRow}%
}%
}
My attempt, based on
- How do I use the ampersand (&) inside a foreach or conditional (or other group/environment) when building tables?
- Build tabular content via \foreach
which yields
may not be the best approach. The current problems with it include:
A blank like is output when a row is to be suppressed.
The column separators are missing. Including a column separators in the call to
\AddTableTokens{& #1}
in the\ColumnL
macro leads toMisplaced alignment tab character &.
I was expecting a problem in that the last row would not be printed as there was no subsequent
T
column, but for some bizarre reason, the last row,Label 4
, is printed first!
Code:
\documentclass{article}
\usepackage{collcell}
\usepackage{tabularx}
\usepackage{etoolbox}
\usepackage{xstring}
\usepackage{showframe}
%% This is based on:
%% https://tex.stackexchange.com/q/165126/4301
%% https://tex.stackexchange.com/q/175568/4301
%%
\makeatletter
\newcommand*{\@MyTempTableTokens}{}%
\newtoks\@tabtoks
%%% assignments to \@tabtoks must be global, in case they are done in \foreach
\newcommand\AddTableTokens[1]{\global\@tabtoks\expandafter{\the\@tabtoks#1}}
\newcommand\eAddTableTokens[1]{% Do NOT add a tailing \\ for each line
\protected@edef\@MyTempTableTokens{#1}%
\expandafter\AddTableTokens\expandafter{\@MyTempTableTokens \\}%
}%
%%% variable should be operated on always locally or always globally
\newcommand*\ResetTableTokens{\global\@tabtoks{}}
\newcommand*\PrintTableTokens{\the\@tabtoks}
\makeatother
\newcommand{\ColumnL}[1]{%
\AddTableTokens{#1}% <--- Need a leading & here
\IfStrEq{#1}{}{}{% Enable printing of row if non-empty content encoutered
\global\toggletrue{DisplayThisRow}%
}%
}
\newtoggle{DisplayThisRow}%
\togglefalse{DisplayThisRow}%
\newcommand{\TitleColumn}[1]{% We are starting a new row
%% If there was a previous row that needed to be output, display that now
\iftoggle{DisplayThisRow}{%
\PrintTableTokens% Print prior row
\global\togglefalse{DisplayThisRow}% Assume entire row is empty
}{%
%\vspace*{-\baselineskip}% Attempt to fix empty rows.
}%
\ResetTableTokens%
\AddTableTokens{#1}% Start a new row with the row label
}
\newcolumntype{L}{>{\collectcell\ColumnL}l<{\endcollectcell}}
\newcolumntype{T}{>{\collectcell\TitleColumn}X<{\endcollectcell}}
\begin{document}
%\showcols
\noindent
\begin{tabularx}{\linewidth}{@{}TLL@{}}
Label 1 & 62 & 79 \\
Label 2 & & \\
Label 3 & & 31 \\
Label 4 & 45 & \\
\end{tabularx}
\end{document}