# How do I forward a length from a command into a column specifier?

I'm using longtable where I want vertical bars separating cells, although not for the table headers. I have 8 columns (but show only 3 here as example) and want to re-use the same lengths on the main longtable as well as all multicolumn specifiers.

In this example, I only use one heading in one table, but with multiple headings (first page, last page, the other pages), I'll have to specify the same column lengths over and over again.

So what I have:

\documentclass[a4paper,10pt]{article}
\usepackage{longtable}
\usepackage{array}
\usepackage{ifthen}
\usepackage{xifthen}

\newcolumntype{C}[1]{>{\centering\let\newline\\\arraybackslash\hspace{0pt}}b{#1}}
\newcolumntype{L}[1]{>{\raggedright\let\newline\\\arraybackslash\hspace{0pt}}b{#1}}
\newcolumntype{R}[1]{>{\raggedleft\let\newline\\\arraybackslash\hspace{0pt}}b{#1}}

\begin{document}

\begin{longtable}[l]{|@{}L{0.2\textwidth}@{}|@{}C{0.5\textwidth}@{}|@{}R{0.3\textwidth}@{}|}
\hline
\hline
\endlastfoot
1 & 2 & 3 \\
4 & 5 & 6 \\
\end{longtable}

\end{document}

I was thinking of defining the column widths once only in my command \mcw which defines the columns widths for column 1, 2 and 3. So, if I want to try lengths I'm comfortable with, I can change in one place only. My suggestion (which doesn't compile) is:

\documentclass[a4paper,10pt]{article}
\usepackage{longtable}
\usepackage{array}
\usepackage{ifthen}
\usepackage{xifthen}

\newcolumntype{C}[1]{>{\centering\let\newline\\\arraybackslash\hspace{0pt}}b{#1}}
\newcolumntype{L}[1]{>{\raggedright\let\newline\\\arraybackslash\hspace{0pt}}b{#1}}
\newcolumntype{R}[1]{>{\raggedleft\let\newline\\\arraybackslash\hspace{0pt}}b{#1}}

\newcommand*{\mcw}[1]{% My column width
\ifthenelse{#1=1}{0.2\textwidth}{%
\ifthenelse{#1=2}{0.5\textwidth}{%
\ifthenelse{#1=3}{0.3\textwidth}{%
}}}}

\begin{document}

\begin{longtable}[l]{|@{}L{\mcw{1}}@{}|@{}C{\mcw{2}}@{}|@{}R{\mcw{3}}@{}|}
\hline
\hline
\endlastfoot
1 & 2 & 3 \\
4 & 5 & 6 \\
\end{longtable}

\end{document}

What am I doing wrong? Can't a newcommand (mcw in this case) "return" a length and pass it as an argument into another command (L, C and R in this case)?

-

The value passed as the length argument has to expand to a length (so that it works in \setlength. ifthenelse does not work by expansion alone. You can define it this way:

\newcommand*{\mcw}[1]{% My column width
\ifcase#1%
% 0
\or
0.2\or
0.4\else
0.3\fi
\textwidth}

I reduced the 0.5 a bit otherwise the page is over-full because of the vertical rules.

-
Thanks, works like a charm! Please explain why you chose ifcase. Is it better than ifthenelse per se, or does this work because you moved the multiplication with \textwidth out of the ifcase expression? –  gustaf r Dec 16 '12 at 15:30
\ifcase is a tex primitive that takes a number as #1 and causes just one of the or branches to expand, all the other branches are skipped as for an \iffalse. \ifthenelse first parses an infix syntax for or and and and then does various temporary macro definitions in case it needs to compare strings and generally does lots of other stuff that is not allowed inside a length assignment. Moving the textwidth to the end just saved a bit of token space it would have worked the same to have \textwidth in each clause. –  David Carlisle Dec 16 '12 at 16:39